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!!
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 implementing recyclerview with multiple layouts.Usually we have multiple viewholders for different layouts and override other methods as per the required layout.I have successfully implemented this.But now i have a different scenario like: A recyclerview that shows some videos (say 3) then another layout(say layout x), again 3 videos and then again layout x and so on.Suppose i have 10 videos then in this case the itemcount would be 10 + 3 as 3 layout x would be displayed.But the videos are loaded while scrolling.So how can i determine the number of views to return in getItemCount();
I mean
#Override
public int getItemCount() {
return ListofVideos.size() + "WHAT??"
}
layout is like this
If all the videos are loaded at at once then it is easy to calculate the number of views like if i have 21 videos i would have total 27 views(i.e 21 videos and 6 layout X views). But when the list is loaded on scroll how can i determine the number of views?
Your Adapter is responsible to populate view so it has all views of your RecyclerView while your ListofVideos (may) have only video links.
Whenever you scroll your RecyclerView, Adapter is responsible to inflate views.
What you should do?
Create an interface
public interface BaseItem {
int ITEM_TYPE_HEADER = 0;
int ITEM_TYPE_SUB_HEADER = 1;
int ITEM_TYPE_ROW_NORMAL = 2;
int getItemType();
}
And implement this interface with your adapter's video item like
public class YourAdapterVideoItem implements BaseItem {
// rest of your code
#Override
public int getItemType() {
return ITEM_TYPE_ROW_NORMAL;
}
}
Create your adapter's header item
public class YourAdapterHeaderItem implements BaseItem {
// rest of your code
#Override
public int getItemType() {
return ITEM_TYPE_HEADER;
}
}
Update your adapter with
public class YourAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private List<BaseItem> items = new ArrayList<BaseItem>();
#Override
public BaseRecyclerViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
BaseRecyclerViewHolder holder;
switch (viewType) {
case BaseItem.ITEM_TYPE_ROW_NORMAL:
default:
// inflate your default items
break;
case BaseItem.ITEM_TYPE_HEADER:
// inflate your default items
break;
}
return holder;
}
#Override
public void onBindViewHolder(BaseRecyclerViewHolder viewHolder, int position) {
BaseItem base = getItemAt(position);
switch (base.getItemType()) {
case BaseItem.ITEM_TYPE_HEADER:
// populate your header view
break;
case BaseItem.ITEM_TYPE_ROW_NORMAL:
// populate your actual view
break;
}
}
#Override
public int getItemCount() {
return items == null ? 0 : items.size();
}
#Override
public int getItemViewType(int position) {
return getItemAt(position).getItemType();
}
public BaseItem getItemAt(int position) {
return items == null ? null : items.get(position);
}
}
When you want to add header use YourAdapterHeaderItem for your videos use YourAdapterVideoItem.
Hope this helps
Edit
For adding headers in GridLayoutManager have a look at RecyclerView GridLayoutManager with full width header
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