使用 RecyclerView 时 notifydatasetchanged 调用 onCreateViewHolder

Does notifydatasetchanged call onCreateViewHolder when using RecyclerView

我想使用切换器在两个不同的视图之间切换,但使用相同的 RecyclerView。基本上,一旦切换,我希望 RecyclerView 适配器重新调用 onCreateViewHolder(),但这次它将使用不同的布局项文件。

notifydatasetchanged() 是否会导致适配器自行重建?或者有别的办法吗?

是的,它将假定其当前数据集无效,需要重新布局并重新绑定所有布局。

要删除和更新 RecyclerView 中的布局,您可以调用

mRecyclerView.removeView(view);

mRecyclerView.removeViewAt(position);

删除数据集中的对象后

notifyDataSetChanged()RecyclerView

的情况下调用 onBindViewHolder()

我的 RecyclerView Adapter 上的 View 也需要两种类型,一种用于 'regular' 模式,一种用于多 select模式。

因此,您可以覆盖 getItemViewType 以强制适配器为所有视图调用您的 onCreateViewHolder

将此添加到 Adapter 代码中:

public void setActionMode(ActionMode actionMode) {
    this.actionMode = actionMode;
    notifyDataSetChanged();
}

@Override
public int getItemViewType(int position) {
    return (actionMode == null ? 0 : 1);
}

将此添加到 ViewHolder:

@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View view;
    if (viewType == 0) {
        view = inflater.inflate(R.layout.layout_1, parent, false);
    } else {
        view = inflater.inflate(R.layout.layout_2, parent, false);
    }
    ...
}

由于您在 ActionMode 中 return 一个不同的 ViewType,适配器被迫丢弃所有创建的视图,并重新创建所有内容。

我在这个问题上花了6个多小时没有成功。 最后!!! 我在适配器中设置了一个全局变量,每次将视图从列表切换到网格时都必须设置它(在我的例子中)。有趣的是,这种方法就在那里,但我忘了把它做成静态的!!所以我的解决方案可能与您的解决方案有关,请尝试一下,希望能成功。

public static int mCurrentViewType;

然后覆盖 getItemType()

  @Override
    public int getItemViewType(int position) {

       return mCurrentViewType;


    }

我的 toggleItemViewType 方法:

public void toggleItemViewType () {
        if (mCurrentViewType == LIST_ITEM){
            mCurrentViewType = GRID_ITEM;
        } else {
            mCurrentViewType = LIST_ITEM;
        }
    }

我正在从不同的 类 访问变量,这是不对的,但是现在为了 onCreateViewHolder 问题,它起作用了! 如果您有更好的解决方案,那么祝您好运并与我们分享。 不要忘记将全局变量设置为 "static" :)

最简单的解决方案

如果你想刷新 RecyclerView 项目并且 onCreateView() 也被调用,比如 GridList LayoutManagers.

Kotlin

fun refreshRecyclerView(recyclerView:RecyclerView){
     val adapterRef=recyclerView.adapter
     recyclerView.adapter=null
     recyclerView.adapter=adapterRef
     }

Java

void refreshRecyclerView(RecyclerView recyclerView){
        Adapter adapterRef=recyclerView.getAdapter();
        recyclerView.setAdapter(null);
        recyclerView.setAdapter(adapterRef);
        }