我有一个ListView小部件(位于其他UI元素下面),它是不扩展ListActivity的Activity的一部分。我正在尝试编写一个基本特性,在单击ListView时向Button添加额外的项。这些数据是从EditText中获取的。我定义了Adapter (在我的例子中是ArrayAdapter ),用于onCreate()中的ListView,并使用setListAdapter()为ListView设置适配器。但是,当我试图向ListView添加一个额外的项时,将添加两个项来代替一个项(一个项及其副本)。下面对此有更详细的说明。
响应Button单击并在调用notifyDataSetChanged()之前尝试添加额外元素的函数如下:
public void saveButton(View view){
     EditText editText = (EditText) findViewById(R.id.edit_text);
     String data = editText.getText().toString();
     // duplication caused by this line
        b.add(data);
     ArrayAdapter adapter = (ArrayAdapter) listView.getAdapter();
     adapter.add((String)data);
     adapter.notifyDataSetChanged();
}当我不包括这一行时:
B.add(数据);
将单个项目添加到列表中,这是预期的行为,因为adapter.add(Object) 在列表中附加了一个额外的项。然而,更奇怪的是,当我不包括adapter.add(Object) 时,列表项仍然呈现在列表中.。
 public void saveButton(View view){
     EditText editText = (EditText) findViewById(R.id.edit_text);
     String data = editText.getText().toString();
     b.add(data);
     ArrayAdapter adapter = (ArrayAdapter) listView.getAdapter();
     // not calling adapter.add() still includes an item in the list.
     // adapter.add((String)data);
     adapter.notifyDataSetChanged();
}经过一些调试后,我发现这是由于在ArrayList**,中添加了一个数据项,即** b.add(data) ,其中b是字符串的ArrayList,尽管没有调用adapter.add(Object)‘.,但它会导致一个项包含在 ListView 中。
Q1。为什么会发生这种事?
Q2。作为扩展,这是否意味着ArrayList与我的ArrayAdapter“耦合”(因为它是使用ArrayList作为参数构建的),这意味着我不需要调用诸如add()或clear()之类的适配器方法来操作ArrayAdapter?
以下也是我的活动的完整代码:
public class MainActivity extends Activity {
ListView listView;
ArrayList<String> b = new ArrayList<String>();
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    b.add("Liquorice");
    b.add("Dairy Milk");
    b.add("Rice Crispies");
    b.add("Orange-Mint");
    b.add("After-Tens");
    listView = (ListView) findViewById(R.id.list_view);
    ArrayAdapter adapter = new ArrayAdapter<String>(getApplicationContext(),R.layout.layout_file,b);
    listView.setAdapter(adapter);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
}
public void saveButton(View view){
     EditText editText = (EditText) findViewById(R.id.edit_text);
     String data = editText.getText().toString();
     b.add(data);
     ArrayAdapter adapter = (ArrayAdapter) listView.getAdapter();
     adapter.add((String)data);
     adapter.notifyDataSetChanged();
}
}我也看了一下其他类似的帖子,但是他们没有给我我想要的答案。
ArrayAdapter in android to create simple listview
Why can't one add/remove items from an ArrayAdapter?
Duplicated entries in ListView
对此,如有任何指示或解释,将不胜感激。也非常感谢你抽出时间。
发布于 2014-06-30 08:47:26
看来你已经找到答案了。通过向ArrayList提供ArrayAdapter,可以有效地将两者耦合在一起。为了更新数据,只需在ArrayList中添加一个新元素即可。
.add()方法只是实现这一目标的捷径。它所做的就是将提供的元素添加到ArrayList中。您可以以任何方式添加元素,只是不要同时使用这两种方式。
那么,notifyDataSetChanged()有什么意义呢?仅仅因为更新了ArrayList并不意味着ListView知道有新的数据。因此,可能存在新的数据,但视图可能不会刷新自身。调用notifyDataSetChanged()告诉ListView查找新数据并重新绘制自己,以便用户看到更改。
来自ArrayAdapter.notifyDataSetChanged()的Android文档
Notifies the attached observers that the underlying data has been changed and any View reflecting the data set should refresh itself.http://developer.android.com/reference/android/widget/ArrayAdapter.html#notifyDataSetChanged()
发布于 2016-09-02 22:14:15
在适配器上,验证视图是否为null,如果为空,则在if设置值之后,从布局中分配适当的视图。
@Override
public View getView(int position, View convertView, ViewGroup parent) {
     ViewHolder viewHolder;
     if (convertView == null) {
         viewHolder = new ViewHolder();
         LayoutInflater vi = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
         convertView = vi.inflate(R.layout.customswipelayout, parent, false);
         viewHolder.name = (TextView) convertView.findViewById(R.id.rowTextView1);
         viewHolder.price = (TextView) convertView.findViewById(R.id.rowTextView2);
         viewHolder.stockCount = (TextView) convertView.findViewById(R.id.rowTextView3);
         convertView.setTag(viewHolder);
         mItemManger.bindView(view, position);
     }
     /* rest of your adapter code */
}
这是我的一个示例,关闭if语句后,我分配值并返回视图:
viewHolder = (ViewHolder) view.getTag();
final Object object = this.list.get(position);
ImageView cmdDelete = (ImageView) view.findViewById(R.id.cmdDelete);
cmdDelete.setOnClickListener
//more personal code follows
return view;
现在我滚动我的列表,它工作得很好!
https://stackoverflow.com/questions/24486000
复制相似问题