nat*_*rio 22 android recycler-adapter android-recyclerview
对于了解其机制或愿意深入了解源代码的人来说,这是一个关于RecyclerView内部行为的问题.我希望通过对源代码的引用来支持答案.
(向下滚动到'换句话说'以获得更集中的问题)
我需要了解notify*行为(例如notifyItemInserted())是如何排队的.想象一下,我有一个由此列表备份的适配器:
ArrayList<String> list = Arrays.asList("one", "three", "four");
Run Code Online (Sandbox Code Playgroud)
我想补充的价值观zero和two,即失踪.
list.add(1, "two");
// notify the view
adapter.notifyItemInserted(1);
// Seconds later, I go on with zero
list.add(0, "zero");
// notify the view
adapter.notifyItemInserted(0);
Run Code Online (Sandbox Code Playgroud)
这非常简单明了,无话可说.
但是,如果两个动作彼此非常接近,并且两者之间没有布局传递怎么办?
list.add(1, "two");
list.add(0, "zero”);
Run Code Online (Sandbox Code Playgroud)
我现在应该怎么做?
adapter.notifyItemInserted(1);
adapter.notifyItemInserted(0);
Run Code Online (Sandbox Code Playgroud)
或者可能
adapter.notifyItemInserted(2);
adapter.notifyItemInserted(0);
Run Code Online (Sandbox Code Playgroud)
?从适配器的角度来看,列表立即切换one, three, four到zero, one, two, three, four第二个选项似乎更合理.
list.add(0, “zero”);
adapter.notifyItemInserted(0);
list.add(2, “two”);
adapter.notifyItemInserted(...)
Run Code Online (Sandbox Code Playgroud)
现在怎么样?1还是2?该列表之后立即更新,但我确信它们之间没有布局传递.
你遇到了主要问题,我想知道在这些情况下我应该怎么做.真实情况是我有多个异步任务以一个insert()方法结束.我可以排队他们的行动,但是:
要更新回收器,必须执行4个操作:
adapter.notify*()getItem*()和onBind()适配器)并列出更改.当没有并发性时,很容易理解这一点,它们按顺序发生:
1. => 2. => 3. => 4. => (new update) 1. => 2. => 3. => 4. ...
Run Code Online (Sandbox Code Playgroud)
让我们看看步骤之间发生了什么.
我想了解在这种情况下会发生什么.我们该怎么做?我是否应确保在插入新内容之前确实已执行上一次更新的第4步?如果是这样的话?
我之前想过类似的问题,我决定:
如果我想直接在列表末尾插入多个项目并想要为所有人制作动画,我应该:
list.add("0");
list.add("1");
adapter.notifyItemRangeInserted(5, 2); // Suppose there were 5 items before so "0" has index of 5 and we want to insert 2 items.
Run Code Online (Sandbox Code Playgroud)如果我想直接在列表末尾插入多个项目,但想为每个插入的项目分别获取动画,我应该:
list.add("0");
list.add("1");
adapter.notifyItemInserted(0);
mRecyclerView.postDelayed(new Runnable() {
@Override
public void run() {
// before this happens, Be careful to call other notify* methods. Never call notifyDataSetChanged.
adapter.notifyItemInserted(1);
}
}, mRecyclerView.getItemAnimator().getAddDuration());
Run Code Online (Sandbox Code Playgroud)希望这可以提供帮助.
因此,让我们从 RecyclerView 与通知项的简单介绍开始。并且与保存的 ViewGroup 项目的其他列表(例如 ListView)一起使用非常简单。
\n\nRecyclerView 具有已绘制的视图项目队列。并且不知道您的任何更新,无需调用notify(...)方法。当您添加新的 Item 并通知 RecyclerView 时,它会开始一一检查所有 View 的循环。
RecyclerView contains and drawn next objects\nView view-0 (position 0), view-1 (position 1), View-2 (position 2)\n\n// Here is changes after updating\nYou added Item View view-new into (position 1) and Notify\nRecyclerView starts loop to check changes\nRecyclerView received unmodified view-0(position-0) and left them;\nRecyclerView found new item view-new(position 1)\nRecyclerView removing old item view-1(position 1)\nRecyclerView drawing new item view-new(position 1)\n\n// In RecyclerView queue in position-2 was item view-2, \n// But now we replacing previous item to this position\nRecyclerView found new item view-1 (new position-2)\nRecyclerView removing old item view-2(position 2)\nRecyclerView drawing new item view-1(position 2)\n\n// And again same behavior \nRecyclerView found new item view-3 (new position-3)\nRecyclerView drawing new item view-1(position 2)\n\n// And after all changes new RecyclerView would be\nRecyclerView contains and drawn next objects\nView view-0 (position 0), view-new (position 1) view-1 (position 2), View-2 (position 3)\nRun Code Online (Sandbox Code Playgroud)\n\n它只是工作通知函数的主要流程,但应该知道所有这些操作都发生在 UI 线程、主线程上,甚至您可以从异步任务调用更新。并回答您 2 个问题 - 您可以根据需要向 RecyclerView 调用 Notify,并确保您的操作位于正确的队列上。
\n\nRecyclerView 在任何使用中都可以正确工作,更复杂的问题将涉及到您的 Adapter 工作。首先,您需要同步您的适配器操作,例如添加删除项目,并完全拒绝索引使用。例如,对于示例 3 来说会更好
\n\nItem firstItem = new Item(0, \xe2\x80\x9czero\xe2\x80\x9d);\nlist.add(firstItem);\nadapter.notifyItemInserted(list.indexOf(firstItem));\n//Other action...\nItem nextItem = new Item(2, \xe2\x80\x9ctwo\xe2\x80\x9d);\nlist.add(nextItem);\nadapter.notifyItemInserted(list.indexOf(nextItem))\n//Other actions\nRun Code Online (Sandbox Code Playgroud)\n\n更新 |
\n\n与RecyclerView.Adapter相关的文档,您可以在其中看到与 相同的功能notifyDataSetChanged()。如果这RecyclerView.Adapter会调用带有扩展的子项android.database.Observable,请参阅更多关于 Observable。对这个Observable Holder的访问是同步的,直到RecyclerView中的View Element释放使用。
另请参阅支持库版本 25.0 第 9934 - 9988 行中的 RecyclerView;
\n| 归档时间: |
|
| 查看次数: |
7576 次 |
| 最近记录: |