【问题标题】:Force RecyclerView to redraw its items强制 RecyclerView 重绘其项目
【发布时间】:2016-04-08 08:30:53
【问题描述】:

有没有办法重绘RecyclerView的所有项目?

我有一些主题(在 style.xml 中),更改主题后,我需要重绘 RecyclerView

所以我想要一个方法来强制为适配器的每个项目重新调用onCreateViewHolder

我尝试过:

  • 调用adapter.notifyDataSetChanged,但未调用onCreateViewHolder
  • 拨打recyclerView.setVisibility(View.GONE),然后拨打recyclerView.setVisibility(View.VISIBLE)
  • 致电recyclerView.invalidate()
  • 拨打recyclerView.setAdapter(null),然后拨打recyclerView.setAdapter(adapter)
    这适用于 90% 的项目。只有 90% 的商品会获得新款式,但有些商品会保留旧款式

我提到RecyclerView 附加到一个活动,而不是一个片段。

【问题讨论】:

  • 确保从 UI 线程调用 notifyDataSetChanged(),它应该可以工作。
  • @Nanoc notifyDataSetChanged 只强制 onBindNewHolder,而不是 onCreate
  • 对不起,我不熟悉 viewHolder 模式,但我会说你应该调整你的代码以使用它(或者不要使用它)。

标签: android android-recyclerview redraw


【解决方案1】:

我找到了答案! 正确的做法是:

recyclerView.setAdapter(null);
recyclerView.setLayoutManager(null);
recyclerView.setAdapter(myAdapter);
recyclerView.setLayoutManager(myLayoutManager);
myAdapter.notifyDataSetChanged();

在那之后,所有的物品都获得了新的风格!

【讨论】:

  • adapter.doYourStaff();recyclerView.setAdapter(adapter);这2行代码就够了!
  • recyclerView.setAdapter(adapter) 对我来说已经足够了。
  • 这对我也有用,只是我不需要前两行(即空分配)。
  • 我在申请之前检查了 recyclerView 和 myAdapter 是否为空,并且工作正常
【解决方案2】:

再次设置 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
}

【讨论】:

  • 或者,对于 Java RecyclerView.Adapter adapter = myRecyclerView.getAdapter(); myRecyclerView.setAdapter(adapter);
  • 可能是最好的答案:)
  • 我会在 recyclerView.adapter = myAdapter 之前添加 recyclerView.adapter = null 以自动在适配器上调用 onDetachedFromRecyclerView()
【解决方案3】:

如果要强制重绘,需要清空RecycleView的View Pool。你可以使用recyclerView.getRecycledViewPool().clear();

【讨论】:

  • ViewHolders 在我调用 clear 后仍未重新绘制。即使我调用 notifyDataSetChanged。不知何故,仍然缓存的视图被重复使用..
【解决方案4】:

下面的代码行对我有用

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

【讨论】:

    【解决方案5】:

    我知道这是旧的,但我有一种情况,我需要在 notifyDataSetChanged() 之后更改查看器类型。如果适配器已经有数据,onCreateViewHolder 没有被调用,因为 recycleviewadapter 的“回收”部分,所以在onBindViewHolder 中抛出了类型转换错误。

    我能够通过在适配器上调用 notifyDataSetChanged(); 之前调用 myRecyclerView.getLayoutManager().removeAllViews(); 来解决此问题。

    【讨论】:

      【解决方案6】:

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

      myRecyclerView.setAdapter(myAdapter)
      

      【讨论】:

      • 当我需要在退出多选模式后删除选择时,这个答案对我有用。我通过接口方法通知了相关片段,在其中我按照这个答案的建议重置了适配器。
      【解决方案7】:

      在 Amazon Fire HD 上对我有用的唯一解决方案是:

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

      希望对你有帮助!

      【讨论】:

        【解决方案8】:

        看看这个答案:https://stackoverflow.com/a/33342314/4142087

        简而言之,您可以创建不同类型的视图持有者,更改视图类型将强制 RecyclerView 将另一个 ViewHolder 传递给 onBindViewHolder

        如果你使用setTheme,你必须像这样重新创建整个Activity:https://stackoverflow.com/a/14367214/4142087

        【讨论】:

        • 如果应该这样做,那么查看器模式看起来不是最干净的。
        • @DenisCovaci 尝试将数据保存在实例状态并重新创建活动
        【解决方案9】:

        强制 RecyclerView 到 onCreateViewHolder 或重绘其项目#Kotlin

        这对我有用?

                this.runOnUiThread {
                    val adapter = recyclerView.adapter
                    val layoutManager = recyclerView.layoutManager
                    recyclerView.adapter = null
                    recyclerView.layoutManager = null
                    recyclerView.adapter = adapter
                    recyclerView.layoutManager = layoutManager
                    adapter!!.notifyDataSetChanged()
                }
        

        希望对你有帮助

        【讨论】:

        • 您应该补充一点,这种情况适用于从后台执行代码(回调方法)。您的代码不起作用的原因是回调在不同的线程中执行,然后是主线程。
        【解决方案10】:

        在这里尝试了大部分想法之后 - 如果事实证明我的问题归结为使用模拟器。在设备上进行测试时,我对此没有任何问题。

        【讨论】:

          【解决方案11】:

          这对我有用:

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

          如果没有post{}运行则显示空白

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2015-04-23
            • 2011-11-14
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2022-08-08
            相关资源
            最近更新 更多