I am using RecyclerView in my android project and its performance has been really awful. From the answers here, I tried adding adapter.setHasStableIds(true);
to
You can not use adapter.setHasStableIds(true);
with ObservableArrayList/ObservableFields
You must set the adapter's hasStableIds to true BEFORE you assign the adapter to your recyclerview.
YourAdapter adapter = new YourAdapter();
adapter.setHasStableIds(true);
myRecyclerView.setAdapter(adapter);
as the recyclerView source code:
/**
* Indicates whether each item in the data set can be represented with a unique identifier
* of type {@link java.lang.Long}.
*
* @param hasStableIds Whether items in data set have unique identifiers or not.
* @see #hasStableIds()
* @see #getItemId(int)
*/
public void setHasStableIds(boolean hasStableIds) {
if (hasObservers()) {
throw new IllegalStateException("Cannot change whether this adapter has "
+ "stable IDs while the adapter has registered observers.");
}
mHasStableIds = hasStableIds;
} .
so you can workaround it .
if (!adapter.hasObservers()) {
adapter.setHasStableIds(true)
}
In my case, it's because the I put the setHasStableIds(true)
inside the Fragment's onActivityCreated()
. The Fragment
is the main point of my application so it never gets popped from back stack.
class LocalFragment: Fragment() {
private val adapter = LocalAdapter()
override fun onActivityCreated(savedInstanceState: Bundle?) {
adapter.setHasStableIds(true)
}
}
The problem here is that the onActivityCreated()
is called every time the Fragment
is navigated to. However, as the Fragment is still alive in the back stack, the private val adapter
field is still the same object that had its setStableIds(true)
called previously.
class LocalFragment: Fragment() {
private var adapter = LocalAdapter()
override fun onActivityCreated(savedInstanceState: Bundle?) {
adapter = LocalAdapter() // Re-assign the adapter
adapter.setHasStableIds(true)
}
}
Solution is to reassign the RecyclerView.Adapter
object every time the fragment is switched to.