我希望我的RecyclerView不回收一些物品

时间:2016-03-30 15:19:15

标签: android android-layout android-recyclerview

我正在使用RecyclerView内部异构视图as seen in this tutorial

我在RecyclerView中有一些物品也是RecyclerViews。难以想象?假设我要复制Play商店的布局:一个具有垂直线性布局的大型RecyclerView,并由许多元素填充:单个应用程序和应用程序轮播。

如果要添加的项目是单个应用程序的布局,则将使用ID 1,我将添加单个项目的布局。 另外,如果我需要添加一个Carousel,那么我将在主RecyclerView中添加一个元素:另一个带有自己的适配器的RecyclerView。

效果很好。滚动主RecyclerView时除外。为什么?因为某些视图在不再可见时被销毁,然后在onBindViewHolder()方法中重新创建。为什么在这?因为主RecyclerView的适配器正在传递位置X,然后调用OnBindViewHolder()。然后,后者使用自己的适配器创建一个新的RecyclerView并将其分配给它。我想保留这些观点只是因为它们每次重新充气都很重要。

这可能吗?如果是的话,你能告诉我怎么做吗?

6 个答案:

答案 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());
    }

}