I am new to recycler view. My requirement is as follows:
- I have to call a web service that will give two arrays. One with data I need to show in the list. For this purpose, I am using RecyclerView
. The other array is of statuses, which I am showing in spinner. This web service is paginated. I have added pagination and it is working fine.
- When user selects some other element from the spinner, again I have to make a web service call and recycler view data should change.
Currently, in case of pagination I am doing following, once I get more data from the successive pages:
mAccountListingsAdapter.notifyItemRangeInserted(mAccountListingsAdapter.getItemCount(), mListings.size() - 1);
And, when I change data from spinner, I am doing following:
mListings.clear();//Clear the data set
mAccountListingsAdapter.notifyDataSetChanged();//Call notify data set changed on recycler view adapter
getAccountListings();//Fetch new data from the web service and display in recycler view
But, it is suggested that, instead of calling notifyDataSetChanged() directly on recycler view adapter, one should call specific notifyXXX method, to avoid performance and animations issues.
So, I am under doubt, if I am doing right to notify recycler view adapter in onItemSelected()
of spinner, or it should be changed.
P.S. I tried following in the onItemSelected
:
int size = mListings.size();
mListings.clear();
mAccountListingsAdapter.notifyItemRangeRemoved(0, size - 1);
But then it crashed, with following exception:
03-02 12:59:41.046: E/AndroidRuntime(4270): java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid item position 4(offset:0).state:5
I think notifyItemRangeRemoved
is the correct method to use here, but the value you are passing for second parameter is wrong. As per the doc, the second parameter is number of items removed from data set, what you are passing is the position of last item removed.
So the below code should work fine
int size = mListings.size();
mListings.clear();
mAccountListingsAdapter.notifyItemRangeRemoved(0, size);
For more info refer : http://developer.android.com/reference/android/support/v7/widget/RecyclerView.Adapter.html#notifyItemRangeRemoved(int,%20int)
First of all, the method definition for notifyItemRangeRemoved (int, int)
is:
public final void notifyItemRangeRemoved (int positionStart, int itemCount)
The second argument is the count
, not positionEnd
. In your case you are passing size - 1
as the second argument, when it should be size
itself.
int size = mListings.size();
mListings.clear();
// should be notifyItemRangeRemoved(0, size)
mAccountListingsAdapter.notifyItemRangeRemoved(0, size - 1);
Second, notifyDataSetChanged()
is frowned upon because it triggers a rebind and relayout of all visible views. In your case, where the number of visible items is zero, I don't see why notifyDataSetChanged()
would degrade performance. If you are animating the removal of items, go with notifyItemRangeRemoved(0, size)
. Else, its quite alright to use notifyDataSetChanged()
over here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With