Force RecyclerView to redraw its items
AndroidAndroid RecyclerviewRedrawAndroid Problem Overview
Is there any way to redraw all items of RecyclerView
?
I have some Themes (in style.xml) and after changing the theme, I need the RecyclerView
to be redrawn.
So I want a method that will force to re-call onCreateViewHolder
for each items of the adapter.
I tried to:
- call
adapter.notifyDataSetChanged
butonCreateViewHolder
is not called - call
recyclerView.setVisibility(View.GONE)
and thenrecyclerView.setVisibility(View.VISIBLE)
- call
recyclerView.invalidate()
- call
recyclerView.setAdapter(null)
and thenrecyclerView.setAdapter(adapter)
.
This works well for 90% items. Only 90% of items will get the new style, but some items will have the old style
I mention that the RecyclerView
is attached to an Activity, not to a Fragment.
Android Solutions
Solution 1 - Android
I found the answer! The correct way to do this is:
recyclerView.setAdapter(null);
recyclerView.setLayoutManager(null);
recyclerView.setAdapter(myAdapter);
recyclerView.setLayoutManager(myLayoutManager);
myAdapter.notifyDataSetChanged();
After that, all the items are getting the new style!
Solution 2 - Android
Simply setting recyclerview's adapter again worked for me (I wanted RecyclerView to redraw all items' layout again)
/**
* Forces RecyclerView adapter to call createViewHolder() - i.e. redraw all all items' layouts
*/
private fun resetAdapterState() {
val myAdapter = recyclerView.adapter
recyclerView.adapter = myAdapter
}
Solution 3 - Android
If you want to force redraw, you need clear View Pool of RecycleView
. You can use recyclerView.getRecycledViewPool().clear();
Solution 4 - Android
The below lines of code did the trick for me
recyclerview.swapAdapter(myAdapter,false);
recyclerview.setLayoutManager(myLayoutManager);
myAdapter.notifyDataSetChanged();
Solution 5 - Android
I know this is old, but I had a situation where I needed to change the viewholder types after notifyDataSetChanged()
. If the adapter already had data, onCreateViewHolder
was not being called because of the "recycle" part of recycleviewadapter, so a type cast error was being thrown in onBindViewHolder
.
I was able to solve this by calling myRecyclerView.getLayoutManager().removeAllViews();
before calling notifyDataSetChanged();
on the adapter.
Solution 6 - Android
Resetting the Adapter worked for me, I called this inside onConfigChange
myRecyclerView.setAdapter(myAdapter)
Solution 7 - Android
The only solution that worked for me on an Amazon Fire HD was this:
recyclerView.setAdapter(null);
recyclerView.setLayoutManager(null);
recyclerView.getRecycledViewPool().clear();
recyclerView.swapAdapter(myAdapter, false);
recyclerView.setLayoutManager(layoutManager);
myAdapter.notifyDataSetChanged();
Hope it helps!
Solution 8 - Android
Take a look at this answer: https://stackoverflow.com/a/33342314/4142087
Shortly, you can create different types of view holders, changing view type will force RecyclerView to pass another ViewHolder
to the onBindViewHolder
.
If you use setTheme
, you have to recreate whole Activity like this: https://stackoverflow.com/a/14367214/4142087
Solution 9 - Android
Force RecyclerView to onCreateViewHolder or redraw its items #Kotlin
This worked for me
this.runOnUiThread {
val adapter = recyclerView.adapter
val layoutManager = recyclerView.layoutManager
recyclerView.adapter = null
recyclerView.layoutManager = null
recyclerView.adapter = adapter
recyclerView.layoutManager = layoutManager
adapter!!.notifyDataSetChanged()
}
hope this can help
Solution 10 - Android
After trying most of the ideas here - if turns out that my issue was down to using a simulator. When testing on devices I've had no issues with this.
Solution 11 - Android
This works for me:
recyclerView.adapter = recyclerView.adapter
recyclerView.post {
recyclerView.adapter?.notifyDataSetChanged()
}
It shows blank if running without post{}