我正在使用RecyclerView
内部异构视图as seen in this tutorial。
我在RecyclerView中有一些物品也是RecyclerViews。难以想象?假设我要复制Play商店的布局:一个具有垂直线性布局的大型RecyclerView,并由许多元素填充:单个应用程序和应用程序轮播。
如果要添加的项目是单个应用程序的布局,则将使用ID 1,我将添加单个项目的布局。 另外,如果我需要添加一个Carousel,那么我将在主RecyclerView中添加一个元素:另一个带有自己的适配器的RecyclerView。
效果很好。滚动主RecyclerView时除外。为什么?因为某些视图在不再可见时被销毁,然后在onBindViewHolder()
方法中重新创建。为什么在这?因为主RecyclerView的适配器正在传递位置X,然后调用OnBindViewHolder()
。然后,后者使用自己的适配器创建一个新的RecyclerView并将其分配给它。我想保留这些观点只是因为它们每次重新充气都很重要。
这可能吗?如果是的话,你能告诉我怎么做吗?
答案 0 :(得分:56)
使用此:
recyclerView.getRecycledViewPool().setMaxRecycledViews(TYPE_CAROUSEL, 0);
这不会回收viewType TYPE_CAROUSEL
的任何视图,但如果此类型的项目数非常高,那么它会显着降低您的性能,甚至可能导致OOME
修改强>
在阅读 MML13 的回答后,我认为它可能适合您。当您在外部RecyclerView中重新绑定该视图时,您担心旋转木马的项目会被重新充气。如果所有这些轮播都是相同的类型,即它们都使用相同的适配器,您可以将适配器保持在RecyclerView的ViewHolder外部,只需交换数据并在此适配器上调用notifyDataSetChanged()
或notifyItemRangeChanged(...)
rebinded。这将回收所有轮播视图和这些轮播中的所有视图。
答案 1 :(得分:17)
您还可以在适配器的onBindViewholder()方法中设置以下代码。
holder.setIsRecyclable(false);
我已从此链接中提及
http://aphoe.com/blog/prevent-androids-recyclerview-recycling-views/
答案 2 :(得分:9)
因为某些视图在不再可见时会被破坏 在onBindViewHolder()方法中重新创建。
事实并非如此,他们不会再创造,他们只是重新绑定。如果您有位置X的视图(在废料或回收商中)RecyclerView
将使用它并重新绑定它。
我想保留这些观点只是因为它们每次重新充气都很重要。
主RecyclerView
为您保留这些内容。您只需要更改第二个RecyclerView
的适配器数据,然后拨打notifyDataSetChanged
。同时将第二个RecyclerView
适配器存储在主viewHolder
的{{1}}内。
答案 3 :(得分:5)
您可以添加适配器:
@Override
public void onBindViewHolder(final CommentViewHolder viewHolder, final int position) {
viewHolder.setIsRecyclable(false);
}
通知回收商是否可以回收此物品。在setIsRecyclable()
稍后设置为true之前,不可再循环的视图将不会被重用于其他项目。拨打setIsRecyclable()
的电话应始终配对(对setIsRecyclabe(false)
的一次通话应始终与稍后调用setIsRecyclable(true)
相匹配)。可以嵌套成对的调用,因为状态是内部参考计数。
答案 4 :(得分:3)
在活动中设置以下行
recyclerView.getRecycledViewPool().setMaxRecycledViews(1,0);
在RecyclerViewAdapter类中设置以下代码
@Override
public int getItemViewType(int position) {
return 1;
}
答案 5 :(得分:1)
我的代码可用于recycleview中的重置UI。
public class BooleanViewHolder extends BaseViewHolder<ConfigItemBoolean> {
private SwitchCompat configBoolean;
BooleanViewHolder(View view) {
super(view);
configBoolean = view.findViewById(R.id.enable_config_boolean);
configBoolean.setOnCheckedChangeListener((buttonView, isChecked) -> {
((ConfigItemBoolean) getItem(getAdapterPosition())).setValue(isChecked);
DataSet.mConfigDataSet.getConfigItemBooleanMap().put(configPairList.get(getAdapterPosition()).first, ((ConfigItemBoolean) getItem(getAdapterPosition())));
});
}
@Override
void bind(ConfigItemBoolean item, String key) {
configBoolean.setText(item.getDisplayName());
configBoolean.setChecked(item.isValue());
}
}