我有以下问题。我从 Fragment 类中填充 Recyclerview。到目前为止,一切顺利。然而,当我测试我的应用程序并上下滚动填充的回收器列表时,每个项目的内容都会发生变化,也就是它们会被回收......
如何保存每个项目的位置并在滚动后将其内容恢复到相同位置?
有什么建议吗?
这样做
holder.setIsRecyclable(false);
会将您的 RecyclerView
转变为 ListView
改为这样做
只需在 RecyclerAdapter 中重写这两个方法即可
@Override
public int getItemViewType(int position) {
return position;
}
@Override
public long getItemId(int position) {
return position;
}
好问题,这就是你的答案holder.setIsRecyclable(false).
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater inflater = (LayoutInflater) parent.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.product_recycle_buyer_list_item, parent, false);
MyViewHolder holder = new MyViewHolder(view);
holder.setIsRecyclable(false);
return holder;
}
setIsRecyclable(false)
是一个糟糕的解决方案,因为它会在滚动时创建越来越多的视图,这破坏了使用 RecyclerView 的全部意义。它不仅需要更多的 CPU,而且您滚动并看到新项目的次数越多,它使用的内存就越多。如果您显示位图,情况会更糟,因为位图往往会占用大量内存。
您应该做的是实现
onBindViewHolder
将视图绑定到它应该具有的数据。在使用位图的情况下也使用缓存。
您可以查看我制作的示例代码here,它询问了我想解决的另一个问题。
如果有人遇到这种情况,
holder.setIsRecyclable(false)
会这样做,但这样只会让回收者看到列表视图,并且还会消耗更多资源。覆盖 getItemViewType
和 getItemId
应该可以修复它。
正如他们上面所说
setIsRecyclable()
是一个糟糕的选择,并且无法解决它。
覆盖 2 个方法 getItemId
和 getItemViewType
并返回两个方法,这将修复它。
recyclerViewAdapter.setHasStableIds(true)
这将确保每个视图都有一个稳定的 id,因此在滚动时视图将被保留。
override fun getItemId(position: Int): Long {
return id // Ensure `id` is unique for each item
}
override fun getItemViewType(position: Int): Int {
return position
}
如果我正确理解了这个问题,那么当您调用设置适配器时,您不想滚动到上面。 我发现最好的方法是打电话
YourRcv.swapAdapter(YourAdapter, Bolean removeAndRecycleExistingViews); // true if yes false if no
我在包
androidx.recyclerview.widget
,类RecyclerView.java的第1142行找到了这个方法