我有一个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
:Views
可以膨胀的两种类型的Adapter
: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。每当我获得新数据时(例如从数据库中获取),我通过attach
ing刷新片段的布局并从容器活动中对其进行detach
ing:
FragmentClass fragment = (FragmentClass) getSupportFragmentManager().getFragments().get(position); // the fragment's position
getSupportFragmentManager().beginTransaction()
.detach(fragment)
.attach(fragment)
.commit();
这样,你也刷新了RecyclerView
的布局。但你记住这一点:
您需要获取要分离的片段的CORRECT引用。因此,使用FragmentManager
而不是RecyclerView
的适配器来保存对片段的引用。否则,当片段尝试保存其状态时,您将收到IllegalStateException。