强制 RecyclerView 调用 onCreateViewHolder

Force RecyclerView to call onCreateViewHolder

我有一个 RecyclerView 可以将项目显示为列表、小网格或大网格,这可以在运行时更改。根据用户选择的样式,我在 onCreateViewHolder 中展开不同的布局。

我还使用 layoutManger.setSpanSizeLookUp() 在样式之间切换。我的代码看起来像这样

layoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
        @Override
        public int getSpanSize(int position) {
            if(showType == ProductAdapter.SHOW_TYPE_SMALL_GRID)
                return 1;
            else
                return columnCount; //show one item per row
        }
    });

@Override
public void onClick(View v) {
    if(showType == ProductAdapter.SHOW_TYPE_SMALL_GRID)
        showType = ProductAdapter.SHOW_TYPE_LARGE_GRID;
    else
        showType = ProductAdapter.SHOW_TYPE_SMALL_GRID;


    int firstVisibleItem = layoutManager.findFirstVisibleItemPosition();
    adapter = new ProductAdapter(getActivity(), productList, showType);
    recyclerView.setAdapter(adapter);
    layoutManager.scrollToPosition(firstVisibleItem);
}

问题是强制调用 onCreateViewHolder 每次用户更改样式时我都在创建一个新对象。还有别的办法吗?!强制召回 onBindViewHolder()。我只是使用 adapter.notifyDataSetChanged() 如何获得与 onCreateViewHolder? 类似的东西

任何不使用多个适配器的解决方案就足够了!

您需要做的是:

  1. 修改你的Adapter

  • 指定您的 Adapter 可以充气的两种 Views

private static final int LARGE_GRID_ITEM = -1;
private static final int SMALL_GRID_ITEM = -2;
  • 创建一个可以存储当前类型的字段mCurrentType

  • 使用你的 Adapter's getItemViewType。例如像这样:

@Override
public int getItemViewType (int position) {
    return mCurrentType;
}
  • 在您的 createViewHolder 中使用 viewType 来决定您需要创建哪种类型的 ViewHolder

public final RecyclerView.ViewHolder createViewHolder (ViewGroup parent, int viewType){
    if (viewType == LARGE_GRID_ITEM) {
        //return large grid view holder
    } else {
        //return small grid view holder
    }
}
  • 另外你可以创建方法:

public void toggleItemViewType () {
    if (mCurrentType == LARGE_GRID_ITEM){
        mCurrentType = SMALL_GRID_ITEM;
    } else {
        mCurrentType = LARGE_GRID_ITEM;
    }
}

public boolean displaysLargeGrid(){
    return mCurrentType == LARGE_GRID_ITEM;
}
  1. 修改您发布的代码:

layoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
        @Override
        public int getSpanSize(int position) {
            if (adapter.displaysLargeGrid()) {
                return 1;
            } else {
                return columnCount; //show one item per row
            }
        }
    });

@Override
public void onClick(View v) {
    adapter.toggleItemViewType();
    adapter.notifyDataSetChanged();
}

这不是最佳选择,但最好创建一个新的 Adapter,它将调用 onCreateViewHolder()。这样你就可以避免你的麻烦,代价是非常小的性能问题。