6

I have a custom ArrayAdapter that uses an ArrayList<OrderedProductItem> for my ListView. Inside this ListView I have an AutoCompleteTextView that also uses a custom ArrayAdapter with an ArrayList<Product>. On initialization this AutoCompleteTextView contains the Names of all Products (around 1250), minus 1 (the OrderedProductItem's Product).

The User can then use a Spinner to select a Product-Tag and I create a filtered ArrayList<Product>, so I only get a list of all Products containing this Product-Tag (still minus the 1). So, my question is: What is the best way to replace an ArrayAdapter's object-list?

I know I can just re-create and re-assign a new ArrayAdapter instance in my ListActivity:

myAdapter = new MyAdapter(this, R.layout.item_view, myList);
setListAdapter(myAdapter);

I also know I can use a clear and then an addAll to replace everything:

// NOTE: myAdapter.setNotifyOnChange is kept on default (true)
myAdapter.clear();
myAdapter.addAll(myList);

I guess the second one is probably best, since we don't want to create a new Instance every time, or does ArrayAdapter have some kind of method like setArray() and I just missed it when looking for it? Or is there even another way that is better for performance than this second option?

Kevin Cruijssen
  • 9,153
  • 9
  • 61
  • 135
  • why are you scared of the performance? – Blackbelt Jul 31 '14 at 07:48
  • @blackbelt Well, first of it's Mobile, so performance should always be a concern. Also, each of my ListView-items contains around 10 View-elements each (Spinner, ImageView, AutoCompleteTextView, etc.) All in all I already managed to make the performance a lot better by using sorted Lists and re-using instances, and right now I want to keep it this way. Also, I mainly made this question since I couldn't find a `setArray()` and the second part was a for-loop adding them one by one, but while making the question I found the `addAll()` (which still uses a loop behind the scenes I can imagine.) – Kevin Cruijssen Jul 31 '14 at 07:54
  • performance are a concern if you have performance issues. Back to the main question, the heavier operation is `getView`, that has to inflate/measure/layout/draw the ListView's children, and in both of case you are scheduling *it*. In my opinion it does make any difference – Blackbelt Jul 31 '14 at 07:57
  • Actually, it does make a difference. Creating and setting a new adapter will clear and reset the list and recycler - the views that could have been reused are released and have to be recreated – FunkTheMonk Jul 31 '14 at 08:00

2 Answers2

11

Here you want to change data of customAdapter make a public method in adapter

public void updateData(ArrayList<T> list){
 mAdapterProductList=list;
}

and now whenever u want to update data use these codes:

adpter.updateData(mUpdatedList);
adapter.notifyDataSetChanges();

No need to re-instantiate your adapter

Pradeep Kumar
  • 777
  • 6
  • 21
  • 1
    You can also call notifyDataSetChanges() inside adapter updateData(ArrayList list) method. – Pradeep Kumar Dec 27 '16 at 16:41
  • 1
    This worked for me but I also had to override the getCount() method to return the sizeof my list. – Stephen Docy May 29 '18 at 07:09
  • Is `mAdapterProductList = list;` the same as `mAdapterProductList.clear();` + `mAdapterProductList.addAll(list);` ? – Rohan Taneja Jun 05 '19 at 04:50
  • @rohan-taneja. Yup, it will work the same. just add notifyDataSetChanges() in next line – Pradeep Kumar Jun 11 '19 at 06:20
  • @PradeepYaduvansy can you please look into this? : https://stackoverflow.com/questions/56454443/clear-addall-vs-re-initialise-list-recyclerviewadapter-android?noredirect=1#comment99502533_56454443 – Rohan Taneja Jun 11 '19 at 14:58
0

Create callback interface and use it

public MyAdapter extends ... {

    public interface GetActualListCallback {
        List<OrderedProductItem> getList();
    }

    private GetActualListCallback mCallback;

    public MyAdapter(Context context, int resId, GetActualListCallback callback) {
        super(context, resId)
        mCallback = callback;
    }

    public int getCount() {
        return mCallback.getList().size();
    }

        ....

}

In your activity implement this interface.

myAdapter = new MyAdapter(this, R.layout.item_view, this);
setListAdapter(myAdapter);

After update list just call notifyDataSetChanged() on myAdapter

Igor Shashkin
  • 45
  • 1
  • 6