简体   繁体   English

强制 RecyclerView 重绘其项目

[英]Force RecyclerView to redraw its items

Is there any way to redraw all items of RecyclerView ?有没有办法重绘RecyclerView的所有项目?

I have some Themes (in style.xml) and after changing the theme, I need the RecyclerView to be redrawn.我有一些主题(在 style.xml 中),更改主题后,我需要重绘RecyclerView

So I want a method that will force to re-call onCreateViewHolder for each items of the adapter.所以我想要一个方法来强制为适配器的每个项目重新调用onCreateViewHolder

I tried to:我尝试过了:

  • call adapter.notifyDataSetChanged but onCreateViewHolder is not called调用adapter.notifyDataSetChanged但未调用onCreateViewHolder
  • call recyclerView.setVisibility(View.GONE) and then recyclerView.setVisibility(View.VISIBLE)调用recyclerView.setVisibility(View.GONE)然后recyclerView.setVisibility(View.VISIBLE)
  • call recyclerView.invalidate()调用recyclerView.invalidate()
  • call recyclerView.setAdapter(null) and then recyclerView.setAdapter(adapter) .调用recyclerView.setAdapter(null)然后recyclerView.setAdapter(adapter)
    This works well for 90% items.这适用于 90% 的项目。 Only 90% of items will get the new style, but some items will have the old style只有 90% 的物品会得到新款式,但有些物品会有旧款式

I mention that the RecyclerView is attached to an Activity, not to a Fragment.我提到RecyclerView附加到 Activity,而不是 Fragment。

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!在那之后,所有的项目都得到了新的风格!

Simply setting recyclerview's adapter again worked for me (I wanted RecyclerView to redraw all items' layout again)简单地设置 recyclerview 的适配器再次对我有用(我希望 RecyclerView 再次重绘所有项目的布局)

/**
 * Forces RecyclerView adapter to call createViewHolder() - i.e. redraw all all items' layouts
 */
private fun resetAdapterState() {
    val myAdapter = recyclerView.adapter
    recyclerView.adapter = myAdapter
}

If you want to force redraw, you need clear View Pool of RecycleView .如果要强制重绘,则需要清除RecycleView的 View Pool 。 You can use recyclerView.getRecycledViewPool().clear();您可以使用recyclerView.getRecycledViewPool().clear();

The below lines of code did the trick for me下面的代码行对我有用

recyclerview.swapAdapter(myAdapter,false);
recyclerview.setLayoutManager(myLayoutManager);
myAdapter.notifyDataSetChanged();

I know this is old, but I had a situation where I needed to change the viewholder types after notifyDataSetChanged() .我知道这很旧,但是我遇到了需要在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 .如果适配器已经有数据,则不会调用onCreateViewHolder ,因为 recycleviewadapter 的“回收”部分,因此会在onBindViewHolder中引发类型转换错误。

I was able to solve this by calling myRecyclerView.getLayoutManager().removeAllViews();我可以通过调用myRecyclerView.getLayoutManager().removeAllViews();来解决这个问题。 before calling notifyDataSetChanged();在调用notifyDataSetChanged(); on the adapter.在适配器上。

重置适配器对我有用,我在onConfigChange内部调用了这个

myRecyclerView.setAdapter(myAdapter)

The only solution that worked for me on an Amazon Fire HD was this:在 Amazon Fire HD 上对我有用的唯一解决方案是:

recyclerView.setAdapter(null);
recyclerView.setLayoutManager(null);
recyclerView.getRecycledViewPool().clear();
recyclerView.swapAdapter(myAdapter, false);
recyclerView.setLayoutManager(layoutManager);
myAdapter.notifyDataSetChanged();

Hope it helps!希望能帮助到你!

Take a look at this answer: https://stackoverflow.com/a/33342314/4142087看看这个答案: 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 .很快,您可以创建不同类型的视图持有者,更改视图类型将强制 RecyclerView 将另一个ViewHolder传递给onBindViewHolder

If you use setTheme , you have to recreate whole Activity like this: https://stackoverflow.com/a/14367214/4142087如果您使用setTheme ,您必须像这样重新创建整个活动: https ://stackoverflow.com/a/14367214/4142087

This works for me:这对我有用:

recyclerView.adapter = recyclerView.adapter
recyclerView.post {
    recyclerView.adapter?.notifyDataSetChanged()
}

It shows blank if running without post{}如果在没有post{}

Force RecyclerView to onCreateViewHolder or redraw its items #Kotlin强制 RecyclerView 到 onCreateViewHolder 或重绘其项目#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希望这可以帮助

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.在设备上进行测试时,我对此没有任何问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM