【问题标题】:Refreshing RecyclerView adapter every 1 second每 1 秒刷新 RecyclerView 适配器
【发布时间】:2017-07-18 05:32:51
【问题描述】:

以下是我对回收站视图的实现。

recycler 视图正在刷新,但视图滞后很多,因此滚动不流畅。 如果我不刷新数据,recyclerView 是流畅的。 问题在于只刷新..!!

我需要在 RecyclerView 中每 1 秒完全刷新一次数据,保持相同的滚动位置。

xml

 <android.support.v7.widget.RecyclerView
    android:id="@+id/recyView_disp_pgms"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:divider="@null" />

活动:

RecyclerView recyView_disp_pgms = (RecyclerView) findViewById(R.id.recyView_disp_pgms);

DisplayProgramsAdapterRecycler pgmAdapter = new DisplayProgramsAdapterRecycler(programsList);
LinearLayoutManager layoutManager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
recyView_disp_pgms.setLayoutManager(layoutManager);
recyView_disp_pgms.setAdapter(pgmAdapter);


handler = new Handler();
    runnable = new Runnable() {
        @Override
        public void run() {
            System.out.println("AllPgm Runflag : " + runflag);
            programList = // Get List from database

           if (programsList != null && programsList.size() > 0) {
            if (pgmAdapter != null && pgmAdapter.getItemCount() > 0) {
                pgmAdapter.resetData(programsList);
            }
        }


            handler.postDelayed(this, 1000);
        }
    };

    handler.post(runnable);

适配器:

 public void resetData(ArrayList<ProgramDetails_Table> programsList) {
    this.programDetailsList = programsList;
    this.notifyDataSetChanged();
}

问题 - 仅在每 1 秒刷新一次数据时才会出现 recyclerView 的滞后滚动

尝试关注其他帖子;但仍然没有运气。 请帮忙..!!

【问题讨论】:

  • 你说'回收站视图令人耳目一新'。那你想要什么?
  • 我希望 recyclerview 滚动流畅;截至目前,它每 1 秒刷新一次列表,并且 recyclerview 相当滞后......!!

标签: android performance android-recyclerview


【解决方案1】:

如果您想刷新您的列表,请找到您的更改,然后通知该位置,因为 notifyDataSetChanged 会重置您的所有数据。 你应该使用轻量级的通知。像这样:

    notifyItemChanged(yourPosition);
    notifyItemInserted(yourPosition);
    notifyItemRemoved(yourPosition);

或者,如果您在某个范围内获得多个更改,则可以使用:

notifyItemRangeChanged(yourPosition);//and etc

【讨论】:

  • 我想刷新整个列表;因为我不知道列表中的哪些项目已更改以及更改了多少。我使用了 notifyItemRangeChanged(0,list.size());这会使回收站视图更慢
  • @RiteshKarmare notifyItemRangeChanged(0,list.size());与 notifyDataSetChanged 相同,我建议您计算您的 programList 更改(如果更改计数小于您的列表大小),然后通知这些更改,因为大 arrayList 上的 notifyDataSetChange 很慢,您无法使其更快。
  • 在我的 recyclerView 项目中有 4 个 textView ;如果对于两个项目,其中一个文本视图是更改我如何更新适配器....我如何跟踪哪个项目被更改
  • @RiteshKarmare,RecycleView 适配器的更新是通过异步调用发生的。这就是为什么有这么多回调。当您执行插入/删除并执行 notifyDataSetChange() 时,适配器知道您想要更新并且它会更新。
  • 我想继续刷新整个适配器每 1 秒,whick 正在更新.. 问题是 recyclerView 的滚动视图滞后
【解决方案2】:

使用DiffUtil。不要使用notifyDataSetChanged

据此https://developer.android.com/reference/android/support/v7/util/DiffUtil.html

DiffUtil 是一个实用类,可以计算两者之间的差异 两个列表并输出一个更新操作列表,该列表将 第一个列表进入第二个列表。

它可用于计算 RecyclerView Adapter 的更新。

notifyDataSetChanged 方法不同,它不会重新加载整个列表,因此具有更好的性能。

而且您不必像 RecyclerView.Adapter 中的其他 notifyData 方法那样手动查找新列表和旧列表之间的差异。

【讨论】:

  • 你需要解释 DiffUtil 是什么,做什么,否则这个答案可能会因为质量太低而被删除
【解决方案3】:

删除您的行 this.programDetailsList = programsList; 并添加以下内容。这是一个简单的 hack,一种让您了解异步回调的方法。

/* I have done adding one element and then deleting the same element as the last element of programsList */
/* adding and deleting triggers notifyDataChange() callback */

//add an element in index 0 as the last element into the programList
programsList.add(programsList.size() - 1, programsList.get(0));

//remove the same last element from ProgramList
programsList.add(programsList.size() - 1);

//now it works
this.notifyDataSetChanged(programsList.size() - 1);

【讨论】:

  • notifyDataSetChanged() 正在现有代码中工作....问题在于 recyclerView 滚动滞后
  • @RiteshKarmare,notifyDataSetChanged() 是一个回调,由后端的 AsyncTask 控制。 notifyDataSetChanged(index) 仅跟踪特定索引中的数据集更改,因此效率更高。我将 programList.size() -1 作为索引背后的逻辑是 ==> 回收器视图不断更新列表项,最后一个更新的项目位于 programList.size() -1。如果您的 programList.size() 太大,您的屏幕只能容纳 5 个项目(例如),那么当您执行 notifyDataSetChanged(0) 时,系统必须创建新的 ListItem 以在您的回收站视图中容纳新项目。
  • 懒惰的,你正在制作,因为你没有回收列表项;相反,您应该使用programsList.size() - 1 作为索引。
【解决方案4】:

确保在 resetData 函数中调用 notifyDataSetChanged()。

另外,试试这个而不是直接分配给 programList

programList.clear();
programList.addAll(arrayListOfDataFromServer);

【讨论】:

  • 而不是将新的 ArrayList 分配给 programList 尝试清除它并使用 addAll 将新列表中的每个值添加到 programList,检查编辑的答案
  • 我也尝试过上述解决方案;但这里的问题似乎是由于 1 秒刷新而导致滚动延迟
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-11-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-29
相关资源
最近更新 更多