Android - ArrayAdapter duplicates ListView items

馋奶兔 提交于 2019-12-12 15:17:01

问题


I have a ListView widget (positioned below other UI elements) that is part of an Activity that does not extend ListActivity. I am trying to write a basic feature that adds extra items to the ListView upon clicking a Button. This data is obtained from an EditText. I define the Adapter, an ArrayAdapter in my case, for the ListView in onCreate() and set the adapter for the ListView using setListAdapter(). However when I try to add an extra item to the ListView two items are added in the place of one (an item and its duplicate). More detail on this below.

The function that responds to the Button click and attempts to add an extra element before calling notifyDataSetChanged() is as:

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

When I do not include this line:

b.add(data);

a single item is added to the list which is expected behaviour as adapter.add(Object) appends an extra item to the list. However even queerer, is that when I do not include adapter.add(Object) a list item is still rendered in the list.

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

After a bit of debugging I found that this is owing to the addition of a data item to the ArrayList, i.e. b.add(data) where b is an ArrayList of Strings, causes an item to be included in the ListView despite not calling adapter.add(Object)`.

Q1. Why is this happening ?

Q2. As an extension, does this mean that the ArrayList is 'coupled' to my ArrayAdapter (as it was constructed using the ArrayList as a argument) implying that I needn't call adapter methods like add() or clear() to manipulate my ListView ?

Here is the full code for my Activity as well:

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

}

I also had a look around other SO posts, but they have not given me the answers I was looking for.

ArrayAdapter in android to create simple listview

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

Duplicated entries in ListView

Any direction or an explanation on this would be most appreciated. Also thank you very much for your time.


回答1:


It looks like you've already tracked down the answer. By providing the ArrayList to the ArrayAdapter, you have, effectively, coupled the two. In order to update the data, all you need to do is add a new element into the ArrayList.

The .add() method is just a shortcut to this. All it does is add the provided element into the ArrayList. You can add the element either way, just don't do it both ways.

What's the point of notifyDataSetChanged() then? Just because you update the ArrayList doesn't mean that the ListView knows there is new data. Thus, new data might exist, but the view might not refresh itself. Calling notifyDataSetChanged() tells the ListView to look for new data and redraw itself so that the user sees the change.


From the Android documentation for ArrayAdapter.notifyDataSetChanged():

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




回答2:


On your adapter, verify if the view is null, if it is, assign the proper views from your layout, after the if, set the values.

@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 */
}

This is an example from one of mine, after I close the if statement, I assign my values and return the view:

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;

Now I scroll through my list and it works perfectly!



来源:https://stackoverflow.com/questions/24486000/android-arrayadapter-duplicates-listview-items

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!