I have a RecyclerView
that can show items as list, small grids or large grid and this can be change at runtime. Depending on what style user chooses i inflate different layout in onCreateViewHolder
.
I also use layoutManger.setSpanSizeLookUp()
to switch between styles. My code looks like this
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);
}
The problem is to force onCreateViewHolder
to be called I'm creating a new object every time user changes the style. Is there any other way?! to force onBindViewHolder()
to be recalled. I simply use adapter.notifyDataSetChanged()
How can i get something similar for onCreateViewHolder?
Any solution that doesn't uses multiple adapters is good enough!
What you need to do is:
Adapter
:Views
that your Adapter
can inflate:private static final int LARGE_GRID_ITEM = -1;
private static final int SMALL_GRID_ITEM = -2;
Create a field that can store current type mCurrentType
Use your Adapter's
getItemViewType
. For example like this:
@Override
public int getItemViewType (int position) {
return mCurrentType;
}
createViewHolder
use the viewType
to decide what type of ViewHolder
you need to create.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();
}