por*_*der 25 android android-recyclerview
我目前有一个回收站视图,其数据每5秒更新一次.要更新列表中的数据,我正在使用
notifyItemChanged(position);
notifyItemRangeChanged(position, mList.size());
Run Code Online (Sandbox Code Playgroud)
每次我调用notifyItemChanged()时,我的recycler视图上的项都会正确更新,但是它会闪烁,因为这会导致再次调用onBindViewHolder.因此,每次都是新鲜的负载.如果可能的话,我怎样才能防止这种情况发生?
Nic*_*oso 55
RecyclerView内置了动画,通常可以添加漂亮的抛光效果.在您的情况下,您将要禁用它们:
((SimpleItemAnimator) mRecyclerView.getItemAnimator()).setSupportsChangeAnimations(false);
Run Code Online (Sandbox Code Playgroud)
(默认的回收器视图动画器应该已经是SimpleItemAnimator的一个实例)
小智 22
您可以禁用项目动画.
mRecyclerView.setItemAnimator(null);
Run Code Online (Sandbox Code Playgroud)
Mar*_*och 16
问题可能不是来自动画,而是来自列表项的不稳定 id。
要使用稳定的 ID,您需要:
- setHasStableIds(true)
在 RecyclerView.Adapter 中,我们需要设置 setHasStableIds(true);true 表示此适配器将发布唯一值作为数据集中项目的键。Adapter 可以在通知数据更改后使用该密钥来指示它们是否相同。
- 覆盖 getItemId(int position)
然后我们必须覆盖 getItemId(int position),以返回位置处项目的标识长度。我们需要确保没有具有相同返回 id 的不同项目数据。
解决方案的来源是here。
如果你想保留RecyclerView的动画并同时避免item闪烁,可以按照以下步骤操作:
1. 直接改变视图组件状态 2. 直接改变Adapter中的数据 3. 不需要通过调用手动刷新UInotifyItemChanged()
直接改变视图并不会立即改变,更好的方法是使用payload来做到这一点。
在您的适配器中:
override fun onBindViewHolder(
holder: RecyclerView.ViewHolder,
position: Int,
payloads: MutableList<Any>
) {
// Using payload to refresh partly
if (payloads.isNullOrEmpty()) {
// refresh all
onBindViewHolder(holder, position)
return
}
// just change one component's status which would not "flash".
(holder as YourHolder).apply{
// make you view change
// etc. checkBox.isChecked = true
}
}
Run Code Online (Sandbox Code Playgroud)
并使用它:
yourAdapter.notifyItemChanged(position, "sample_pay_load")
Run Code Online (Sandbox Code Playgroud)
小智 7
在您的适配器中使用 stableId。
调用adapter.setHasStableIds(true)并重写getItemId(int position)适配器类中的方法。
另外,为每个项目返回一些唯一的 ID getItemId(int position)。不要只是简单地返回位置。
发生这种情况是因为 Adapter 正在创建新的 ViewHolder 并尝试在新旧 ViewHolder 之间设置动画。这就是为什么所有“禁用动画”答案在技术上都有效。
相反,您只需告诉RecyclerView重新使用 Viewholders即可canReuseUpdatedViewHolder()。请参阅类似问题的答案:
/sf/answers/4229937351/
| 归档时间: |
|
| 查看次数: |
12605 次 |
| 最近记录: |