强制 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?
类似的东西
任何不使用多个适配器的解决方案就足够了!
您需要做的是:
- 修改你的
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;
}
- 修改您发布的代码:
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()
。这样你就可以避免你的麻烦,代价是非常小的性能问题。
我有一个 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?
类似的东西
任何不使用多个适配器的解决方案就足够了!
您需要做的是:
- 修改你的
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;
}
- 修改您发布的代码:
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()
。这样你就可以避免你的麻烦,代价是非常小的性能问题。