Android - ArrayAdapter复制ListView项

时间:2014-06-30 08:35:45

标签: android android-listview android-arrayadapter android-adapter

我有一个ListView窗口小部件(位于其他UI元素下方),它是Activity的一部分,不会扩展ListActivity。我正在尝试编写一个基本功能,在点击ListView时向Button添加额外的项目。此数据来自EditText。我为Adapter中的ArrayAdapter定义了ListViewonCreate(),并使用ListViewsetListAdapter()设置了适配器。但是当我尝试向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。增加(数据);

将单个项目添加到列表中,这是预期的行为,因为adapter.add(Object)会将额外的项目附加到列表中。然而,即使是Qerer,当我不包括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()等适配器方法或清除()来操纵我的ListView

以下是我的活动的完整代码:

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();
}

}

我也看过其他SO帖子,但他们没有给我我想要的答案。

ArrayAdapter in android to create simple listview

Why can't one add/remove items from an ArrayAdapter?

Duplicated entries in ListView

对此的任何指示或解释都将非常感激。也非常感谢你的时间。

2 个答案:

答案 0 :(得分:2)

看起来你已经找到了答案。通过向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()

答案 1 :(得分:0)

在适配器上,验证视图是否为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;

现在我滚动浏览列表,它完美无缺!