4

I have a ListView that is populated by a news server rundown (just a list of story slugs) and an arrayAdapter to modify that ListView.

I can remove items by the 'remove(Object)' function but what if there are multiple instances of 'Object'? remove() only removed the first instance of 'Object'. I cannot remove, for example, the second 'Object' in my array adapter without removing the first one. So my question is how can i work around this?

ex : Rundown A

story 1 
story 2
Break
story 3
story 4
Break
story 5
etc...

so in this example i cannot delete the Second 'Break' because remove('Break') will remove the first one. if i could removeByIndex(5), that would be perfect but....

Ive tried writing my own remove function that creates a whole new adapter with all members but the specified index. here is what i was messing around with.

public ArrayAdapter<String> removeIndex(ArrayAdapter<String> arr, int index) {
    ArrayAdapter<String> temp = new ArrayAdapter<String>(arr.getContext(),R.layout.list_item);
    for(int i =0 ; i<arr.getCount();i++){
        if(i != index) temp.add(arr.getItem(i));
    }
    return temp;
}

Help or suggestions are appriciated.

MoeABM
  • 53
  • 2
  • 6

1 Answers1

5

Handle the collection of strings yourself with a List and pass the object into the constructor of the ArrayAdapter. This leaves you with a reference to the List so you can alter the data while allowing the adapter to manage and display as needed.

Note: When modifying the data object you must call

myAdapter.notifyDataSetChanged()

afterwards - which must also be on the UI thread. Obviously the changes to the list don't have to take place on the UI thread and should most likely not happen on the UI thread.

private ArrayList<String> mData = new ArrayList<String>();
private ArrayAdapter<String> mAdapter;

@Override
protected void onCreate(Bundle savedInstanceState) {
    // ...
    // Code that adds the strings
    // Create the list adapter
    mAdapter = new ArrayAdapter<String>(myActivity.this, android.R.layout.simple_list_item_1, mData);
}

private void removeItem(int index) {
    mData.removeAt(index);
    myActivity.this.runOnUiThread(new Runnable() {
        public void run() {
            mAdapter.notifyDataSetChanged();
        }
    }
}
Austin Hanson
  • 21,820
  • 6
  • 35
  • 41
  • Please correct me if I'm wrong. by doing it this way (and also the way i'm doing it now) I have to create a new adapter each time I delete an object therefore must call setListAdapter() which loses my scroll position in the ListView. – MoeABM Aug 06 '11 at 05:10
  • 1
    Beautiful! such an easy and elegant solution. Thanks. – MoeABM Aug 06 '11 at 05:31
  • http://developer.android.com/reference/android/widget/ArrayAdapter.html#setNotifyOnChange(boolean) should mean you don't have to manually call `notifyDataSetChanged()` – Dandre Allison Jan 29 '13 at 00:08
  • This is not thread safe. In the rare situation that the UI thread try to access the list (due to an user's scroll, for instance) while another thread is updating the list, your app may crash.Use a thread safe list: http://developer.android.com/reference/java/util/Collections.html#synchronizedList%28java.util.List%3CT%3E%29 – aalmeida Nov 29 '14 at 20:04