I am using GridLayoutManager for recyclerview with spansize of 1 and 2
GridLayoutManager.SpanSizeLookup spanSizeLookup = new GridLayoutManager.SpanSizeLookup() {
#Override
public int getSpanSize(int position) {
switch (adapter.getItemViewType(position)) {
case TYPE_HEADING:
return 1;
default:
return 2;
}
}
};
RecyclerAdapter adapter = new RecyclerAdapter(mContext, arrItems);
recyclerView.setLayoutManager(gridLayoutManager);
recyclerView.setAdapter(adapter);
The recyclerview shows perfectly. But then if I remove one item from the recyclerview the spansize reverses ie spansize for TYPE_HEADING becomes 2 and 1 otherwise.
Code to remove item.
arrItems.remove(position);
notifyItemRemoved(position);
How to fix this
Related
i use GridLayoutManager to RecyclerView but i require every four row this (provide image) ViewType
give me solution
This type view
Assumning all items have similar views Try This:
GridLayoutManager layoutManager = new GridLayoutManager(DashboardActivity.this, 2);
layoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
#Override
public int getSpanSize(int position) {
if (positions you wish to have a different view) {
return 2;
}
return 1;
}
});
RecyclerView supports multiple viewtypes.
Take a look into this:
How to create RecyclerView with multiple view type?
#Override
public int getItemViewType(int position) {
//Every 5th view should be different
return position % 5;
}
#Override
public int getItemCount() {
return 2;
}
I am setting up contact directory in section recyclerview with grid layout manager, what my problem is that header is also set as an item in the span if the span is empty.
I tried using the SpanSizeLookup method. It's not working as I expected.
layoutManager = new GridLayoutManager(getActivity(), 3);
layoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
#Override
public int getSpanSize(int position) {
switch(adapterDocument.getItemViewType(position)){
case SectionedRecyclerViewAdapter.VIEW_TYPE_HEADER:
return 3;
case SectionedRecyclerViewAdapter.VIEW_TYPE_ITEM_LOADED:
return 1;
default:
return 1;
}
}
});
This is what I get
And this is what I really wants:
How to make header should be in next line with full width? Thank you.
there is something with your code, I changed the code in onCreateView from Example1 to:
sectionAdapter = new SectionedRecyclerViewAdapter();
for(char alphabet = 'A'; alphabet <= 'Z';alphabet++) {
List<String> contacts = getContactsWithLetter(alphabet);
if (alphabet == 'B' || alphabet == 'D') {
contacts = Collections.emptyList();
}
if (contacts.size() > 0) {
sectionAdapter.addSection(new ContactsSection(String.valueOf(alphabet), contacts));
}
}
RecyclerView recyclerView = (RecyclerView) view.findViewById(R.id.recyclerview);
GridLayoutManager glm = new GridLayoutManager(getContext(), 3);
glm.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
#Override
public int getSpanSize(int position) {
switch(sectionAdapter.getSectionItemViewType(position)) {
case SectionedRecyclerViewAdapter.VIEW_TYPE_HEADER:
return 3;
default:
return 1;
}
}
});
recyclerView.setLayoutManager(glm);
recyclerView.setAdapter(sectionAdapter);
and it's working fine, this is the result:
How to create a Grid Recyclerview with 3 columns in even number row and 4 columns in odd number row?
lLayout = new GridLayoutManager(getActivity(), 4, LinearLayoutManager.VERTICAL, false); // MAX NUMBER OF SPACES
lLayout.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
#Override
public int getSpanSize(int position) {
return (position % 3 == 0 ? 3 : 4);
}
});
recyclerView = (RecyclerView) view.findViewById(R.id.recyclerView);
recyclerView.setLayoutManager(lLayout);
if (arrayList != null) {
adapter = new RecyclerViewAdapter(getActivity(), arrayList);
recyclerView.setAdapter(adapter);
}
Try this,
// Create a grid layout with 12 columns
// (least common multiple of 3 and 4)
GridLayoutManager manager = new GridLayoutManager(this, 12, GridLayoutManager.VERTICAL, false);
manager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
#Override
public int getSpanSize(int position) {
// 7 is the sum of items in one repeated section
switch (position % 7) {
// first three items span 3 columns each
case 0:
case 1:
case 2:
return 4;
// next four items span 2 columns each
case 3:
case 4:
case 5:
case 6:
return 3;
}
throw new IllegalStateException("internal error");
}
});
recyclerView.setLayoutManager(manager);
Try something like this
layoutManager = new GridLayoutManager(getActivity(), 4);
layoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
#Override
public int getSpanSize(int position) {
if (position % 3 == 0)
return 3;
else
return 4;
}
});
recyclerView.setLayoutManager(layoutManager);
Hope this helps
I am using a RecyclerView with GridLayoutManager to show some items in grid pattern. It's working good and showing items in 2 columns inside grid.
But when the number of items is odd, I want that the last item has to be full width (same as width of RecyclerView).
Is there anyway to do it using GridLayoutManager or I have to build custom design?
Please help.
You could use layoutManager.setSpanSizeLookup method from GridLayoutManager
Here is the way to use that
final GridLayoutManager layoutManager = new GridLayoutManager(context, 2);
layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
layoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
#Override
public int getSpanSize(int position) {
if (mAdapter != null) {
switch (mAdapter.getItemViewType(position)) {
case 1:
return 1;
case 0:
return 2; //number of columns of the grid
default:
return -1;
}
} else {
return -1;
}
}
});
Now you have to determine the viewType in your adapter
#Override
public int getItemViewType(int position) {
return (position == getItemCount() - 1) ? 0 : 1; // If the item is last, `itemViewType` will be 0
}
Keep building better apps!!
I am developing an Android Application for Online Shopping. I have created following view for List of Products using RecyclerView, in that i want to change view on selecting option menu item:
I have created following adapter named ProductAdapter, in that I have implemented code for changing layout in onCreateViewHolder for selecting layout file based on boolean value.
Code of Adapter ProductAdapter:
/***
* ADAPTER for Product to binding rows in List
*/
private class ProductAdapter extends RecyclerView.Adapter<ProductAdapter.ProductRowHolder> {
private List<Product> productList;
private Context mContext;
public ProductAdapter(Context context, List<Product> feedItemList) {
this.productList = feedItemList;
this.mContext = context;
}
#Override
public ProductRowHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View v = LayoutInflater.from(viewGroup.getContext()).inflate(isProductViewAsList ? R.layout.product_row_layout_list : R.layout.product_row_layout_grid, null);
ProductRowHolder mh = new ProductRowHolder(v);
return mh;
}
#Override
public void onBindViewHolder(ProductRowHolder productRowHolder, int i) {
Product prodItem = productList.get(i);
// Picasso.with(mContext).load(feedItem.getName())
// .error(R.drawable.ic_launcher)
// .placeholder(R.drawable.ic_launcher)
// .into(productRowHolder.thumbnail);
double price = prodItem.getPrice();
double discount = prodItem.getDiscount();
double discountedPrice = price - (price * discount / 100);
String code = "";
if(prodItem.getCode() != null)
code = "[" + prodItem.getCode() + "] ";
productRowHolder.prodIsNewView.setVisibility(prodItem.getIsNew() == 1 ? View.VISIBLE : View.INVISIBLE);
productRowHolder.prodNameView.setText(code + prodItem.getName());
productRowHolder.prodOriginalRateView.setText("Rs." + new BigDecimal(price).setScale(2,RoundingMode.DOWN));
productRowHolder.prodDiscView.setText("" + new BigDecimal(discount).setScale(2,RoundingMode.DOWN) + "% off");
productRowHolder.prodDiscRateView.setText("Rs." + new BigDecimal(discountedPrice).setScale(2,RoundingMode.DOWN));
productRowHolder.prodOriginalRateView.setPaintFlags(productRowHolder.prodOriginalRateView.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);
}
#Override
public int getItemCount() {
return (null != productList ? productList.size() : 0);
}
public class ProductRowHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
//Declaration of Views
public ProductRowHolder(View view) {
super(view);
view.setOnClickListener(this);
//Find Views
}
#Override
public void onClick(View view) {
//Onclick of row
}
}
}
After that i have done code for Changing RecyclerView layout from List to Grid and Vice Versa in onOptionsItemSelected, here i am calling mAdapter.notifyDataSetChanged(); so it will call adapter again and change value.
onOptionsItemSelected:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
switch (id) {
case R.id.action_settings:
return true;
case android.R.id.home:
finish();
break;
case R.id.product_show_as_view:
isProductViewAsList = !isProductViewAsList;
supportInvalidateOptionsMenu();
mRecyclerView.setLayoutManager(isProductViewAsList ? new LinearLayoutManager(this) : new GridLayoutManager(this, 2));
mAdapter.notifyDataSetChanged();
break;
}
return super.onOptionsItemSelected(item);
}
I got little bit success like:
Image of Grid layout:
Image of List layout:
BUT NOW WHEN I SCROLL and then CHANGING VIEW is Displaying like:
Grid layout:
List layout:
I dont know why it happens after scrolling. Is there any other way to change view like this.
Today i just saw that this problem is because of ImageView, without it working perfectly.
Help please, You help will be appreciated.
I found solution with the starting of activity I have set LinearLayoutManager like:
mLayoutManager = new LinearLayoutManager(this);
mProductListRecyclerView.setLayoutManager(mLayoutManager);
after that onOptionsItemSelected written like:
case R.id.menu_product_change_view:
isViewWithCatalog = !isViewWithCatalog;
supportInvalidateOptionsMenu();
//loading = false;
mProductListRecyclerView.setLayoutManager(isViewWithCatalog ? new LinearLayoutManager(this) : new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL));
mProductListRecyclerView.setAdapter(mAdapter);
break;
and changing view in onCreateViewHolder like:
#Override
public ProductRowHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View v = LayoutInflater.from(viewGroup.getContext()).inflate(isViewWithCatalog ? R.layout.product_row_layout_list : R.layout.product_row_layout_grid, null);
ProductRowHolder mh = new ProductRowHolder(v);
return mh;
}
From Starting to Ending you have to manage isViewWithCatalog variable for displaying which layout first.
In this SDK samples there is a complete example however it uses one layout file for both LayoutManagers
For keeping the scrolling position when switching the layout they used this function
public void setRecyclerViewLayoutManager(LayoutManagerType layoutManagerType) {
int scrollPosition = 0;
// If a layout manager has already been set, get current scroll position.
if (mRecyclerView.getLayoutManager() != null) {
scrollPosition = ((LinearLayoutManager) mRecyclerView.getLayoutManager())
.findFirstCompletelyVisibleItemPosition();
}
switch (layoutManagerType) {
case GRID_LAYOUT_MANAGER:
mLayoutManager = new GridLayoutManager(getActivity(), SPAN_COUNT);
mCurrentLayoutManagerType = LayoutManagerType.GRID_LAYOUT_MANAGER;
break;
case LINEAR_LAYOUT_MANAGER:
mLayoutManager = new LinearLayoutManager(getActivity());
mCurrentLayoutManagerType = LayoutManagerType.LINEAR_LAYOUT_MANAGER;
break;
default:
mLayoutManager = new LinearLayoutManager(getActivity());
mCurrentLayoutManagerType = LayoutManagerType.LINEAR_LAYOUT_MANAGER;
}
mRecyclerView.setLayoutManager(mLayoutManager);
mRecyclerView.scrollToPosition(scrollPosition);
}
I solved this problem by setting the adapter again to the RecyclerView, after changing the layout manager.
listView.setLayoutManager(new LinearLayoutManager(this));
listView.setAdapter(adapter);
I think after scrolling and changed back to grid view, the first item is not recreated. I solved this by override getItemViewType() and inflate the layout files in onCreateViewHolder accordingly.