【问题标题】:RecyclerView Adapter notifyDataSetChanged not workingRecyclerView 适配器 notifyDataSetChanged 不起作用
【发布时间】:2015-02-27 03:07:36
【问题描述】:

我扩展了

RecyclerView.Adapter<RecyclerView.ViewHolder>

当我打电话时:

mRecyclerView.getAdapter().notifyDataSetChanged();

什么也没发生。

刷新视图的唯一方法是再次设置适配器(see this answer):

mRecyclerView.setAdapter(new MyAdapter(...));

我对这个解决方案有两个问题:

  1. 重新设置适配器时,我可以看到屏幕闪烁
  2. 列表视图返回到第一个位置。

有什么想法吗?

【问题讨论】:

  • 有没有尝试在MyAdapter中封装notifyDataSetChanged方法?例如:在 MyAdapter 中创建“myNotifyDataSetChanged”并从该方法调用 this.notifyDataSetChanged()”。保存 MyAdapter 引用并调用 myAdapterRef.myNotifyDataSetChanged() 而不是 myRecyiclerView.getAdapter().notifyDataSetChanged()。不知道为什么它对我有用(我对 ListView 有这个问题)
  • @helionprime 没有帮助:(
  • 好吧,我的错。我忘了在onBindViewHolder 方法中获取/使用更新的数据。但是眨眼效果呢,怎么才能去掉呢?
  • 好吧,我的坏2。与将图像加载到我的项目中的 imageViews 相关的闪烁效果。这是我正在使用的 UniversalImageLoader (github.com/nostra13/Android-Universal-Image-Loader/issues/376) 的一个已知问题。
  • 你能找到解决问题的方法吗@David。我也有同样的问题。

标签: android android-adapter android-recyclerview notifydatasetchanged


【解决方案1】:

如果notifyDataSetChanged() 没有触发视图更新,那么您可能忘记在您的 RecyclerView 上调用 SetLayoutManager()(就像我一样!)。 只是不要忘记这样做: Java 代码:

LinearLayoutManager layoutManager = new LinearLayoutManager(context ,LinearLayoutManager.VERTICAL, false);
recyclerView.setLayoutManager(layoutManager)

C# 代码,我使用的是 Xamarin。

var layoutManager = new LinearLayoutManager(Context, LinearLayoutManager.Vertical, false);
recyclerView.SetLayoutManager(layoutManager);

在您致电recyclerView.SetAdapter(adapter)之前;

如果您更喜欢在 xml 中声明它,因此您不能在代码中忘记它,您也可以将这些行添加到您的 recyclerView 的 xml 中:

app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
android:orientation="vertical"

【讨论】:

    【解决方案2】:

    如果您的 getItemCount() 返回 0,那么 notifyDataSetChanged() 将不会做任何事情。确保在初始化适配器时传递的是有效数据集。

    【讨论】:

      【解决方案3】:

      根据 javadocs:如果您正在编写适配器,那么如果可以的话,使用更具体的更改事件总是会更有效。依靠notifyDataSetChanged() 作为最后的手段。

      public class NewsAdapter extends RecyclerView.Adapter<...> {    
      
      private static List mFeedsList;
      ...
      
          public void swap(List list){
          if (mFeedsList != null) {
              mFeedsList.clear();
              mFeedsList.addAll(list);
          }
          else {
              mFeedsList = list;
          }
          notifyDataSetChanged();
      }
      

      我正在使用 Retrofit 获取列表,在 Retrofit 的 onResponse() 使用中,

      adapter.swap(feedList);
      

      【讨论】:

      【解决方案4】:

      要更新 recyclerview,我们可以执行以下操作:

      1. 再次创建和设置适配器:

        adapter=new MyAdapter(...);
        mRecyclerView.setAdapter(adapter);
        
      2. 清除模型列表数据,然后通知:

        List<YourModel> tempModel=new ArrayList<>(modelList); 
        modelList.clear();   
        modelList.addAll(tempModel); 
        adapter.notifyDataSetChanged();
        

      【讨论】:

      • 不需要每次都创建一个新的适配器。您只需将新数据传递给现有适配器即可。请看下面我的工作示例。
      【解决方案5】:

      就我而言,除此之外没有任何效果。当需要刷新 RecyclerView 时,我做了:

      array = getNewItems();                    // populates the list with new items
      ((MyAdapter) mAdapter).setValues(array);  // pass the new list to adapter !!!
      mAdapter.notifyDataSetChanged();          // tell the adapter a data set has changed
      

      MyAdapter中,我放了数据的setter:

      public void setValues(List<Item> items){
          this.items = items;
      }
      

      就是这样!

      [注意如果不为适配器设置新值,notifyDataSetChanged 将无法工作。]

      【讨论】:

        【解决方案6】:

        想分享一些东西,我遇到了同样的问题。但我做错的是。 我每次都在创建适配器实例,而不是对那个新实例而不是旧实例执行 notifysetDatachange()。

        所以请确保您通知setDatachange() 的适配器应该是较旧的适配器。 希望下面的例子有帮助..

             MyAdapter mAdapter = new MyAdapter(...)
        
            mRecyclerView.setAdapter(mAdapter );
        
        // TODO 
        mAdapter.modifyData(....);
        mAdapter.notifySetDataChange();
        
        
            MyAdapter extends baseAdapter {
             MyAdapter () {
            }
            modifyData(String[] listData) {
        
            }
        
            }
        

        【讨论】:

          【解决方案7】:

          notifyDataSetChanged() 应该在主线程中调用。

          【讨论】:

          • 这似乎不是问题
          • 谢谢。我的问题是服务中的侦听器,它在其他线程上运行。
          【解决方案8】:

          所以我这样解决了我的问题:orderList 是我传递给 recyclerview 的列表。我们可以在列表中的位置添加项目,这里 0 是列表中的第 0 位。然后调用 adapter.notifyDataSetChanged() 。像魅力一样工作

          1) orderList.add(0,String); 2) orderAdapter.notifyDataSetChanged();

          【讨论】:

            猜你喜欢
            • 2011-04-26
            • 1970-01-01
            • 2018-11-23
            • 2023-03-24
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多