I want to use an expandable recyclerview with grid layout manager, but with specific expanding behaviour which expand to the full width of the screen.
Is there any way or maybe libraries to achieve this? Thank you.
You need to add a transformation in your ViewHolder. Check this post: link
I donĀ“t know if Christopher's link allows for the expandable to occupy the whole 2 grids. There might be a way using a combination of getItemViewType(), and setSpanSizeLookup().
#Override
public int getItemViewType(int position) {
if (position == positionOfClickedItem + 2){
return TYPE_EXPANDABLE;
} else {
return TYPE_CAR_ITEM;
}
}
Bind the data according to its position, and carry the position to your activity to set SpanSizeLookup. You would then have to notify the adapter of a change:
// Create a SpanSizeLookup which returns 2 grids span if its the expandable or 1 otherwise.
gridLayout.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
#Override
public int getSpanSize(int position) {
if (position == positionOfClickedItem) {
return 2;
} else {
return 1;
}
}
});
I think the transformation answer works better but just in case the Span size is important.
Related
I want to add empty spaces between items of a RecyclerView with GridLayoutManager but I can't find anything which solves my problem.
I am creating a custom calendar and I have to make a custom grid from scratch. The first day of the month should be placed farther from the start when it is not the first day of the week.
I have achieved a similar result by passing a firstItemLocation to my RecyclerView adapter and overriding the onBindViewHolder method like this:
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
if (position < firstItemLocation) {
holder.itemView.setVisibility(View.GONE);
} else {
holder.tv.setText(String.format(Locale.US, "%d", list.get(position - firstItemLocation)));
}
}
It works fine but in a hypothetical situation when the user has to scroll it adds random empty spaces and glitches like this.
Any seggestions to make it better without that glitch?
read about "recycling pattern", how it works and why - RecyclerView got its name because of this, so its very important to understand how this works
but in short:
inside onBindViewHolder you have to call desired methods ALWAYS. you are calling setVisibility only inside if and not in else. try with bellow snippet
if (position < firstItemLocation) {
holder.itemView.setVisibility(View.GONE);
holder.tv.setText("")
} else {
holder.itemView.setVisibility(View.VISIBLE);
holder.tv.setText(String.format(Locale.US, "%d", list.get(position - firstItemLocation)));
}
thats because holder may be a "recycled" instance, used previously to draw another list item, and its set up is still applied to views
I am implementing a recycler view with two ViewHolder types. After creating the first item as first-type view holder, I have a list of items of the same, second type. Now, I would like to juxtapose the second type items in order to define a two-column recycler view list considering the second type. Is it possible to do that? I have no idea of what should be implemented in the adapter and honestly I have found no good suggestions here. I guess I might not post my adapter code, since I don't know whether it is possible to do what I aim, I hope a conceptual answer may be sufficient too. I have an image, made with a not good image editor of my smartphone, I hope it is clear:
I am late but I found out a solution.
I associate to the recyclerview a GridLayoutManager with span count = 2.
Since I have, at the top of the recyclerview, an EditText (I use it as a search bar), as you can see in the image, I have to set the lookup of the grid. This is done by setSpanSizeLookup(). So, in the onViewCreated() method of my fragment class that initializes the recyclerview (I have a Fragment hosting the recyclerview), I insert the following code:
GridLayoutManager gridLayoutManager = new GridLayoutManager(getContext(), 2);
gridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
#Override
public int getSpanSize(int position) {
int type = adapter.getItemViewType(position);
if (type == RecyclerAdapter.SEARCH)
return 2;
else
return 1;
}
});
recyclerView.setLayoutManager(gridLayoutManager);
where the part "if (type == RecyclerAdapter.SEARCH) return 2;" means that the view holder for the search bar is going to occupy one whole row, 2 grid cells (since the span = 2).
In my recyclerview adapter, the method getItemViewType is essential:
#Override
public int getItemViewType(int position) {
if (position == 0)
return SEARCH;
else
return DESCRIPTION;
}
where SEARCH and DESCRIPTION are two static final variables.
I have a table to be displayed in RecyclerView. Currently i'm using GridLayoutManager with vertical orientation. Since all my logic depends on the vertical orientation of GridLayoutManager, i'm unable to shift to horizontal orientation or StaggeredLayoutManager. Is there a way to alter RecyclerView children measure so that the first cell of each row can have a different width?
I suggest you to use SpanSizeLookup.
Something like this:
GridLayoutManager manager = new GridLayoutManager(context, 2);
manager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
#Override
public int getSpanSize(int position) {
switch(adapter.getItemViewType(position)) {
// first cell type
case 1:
return 1;
default:
return 2;
}
}
});
And in you adapter you should override getItemViewType and return different types for your cells.
After some source digging, i have found that method GridLayoutManager.calculateItemBorders() is responsible for item width (cachedBorder). But since change that method is private, we cannot override it.
Hope this helps anyone who is facing a similar situation.
Description: I am working on one demo with the functionality that user can select an option from the item of horizontal Recyclerview. In this, I got stuck in below queries.
Queries:
1: How to make Recyclerview cyclic?
For example, I have 10 items named 1,2,3,4,5,6,7,8,9,10. Now if user scrolls the recyclerview then he/she will be able to scroll it endlessly. i.e 1,2,3,4,5...9,10,1,2...9,10,1,2,3..9,10 like this.
To achieve this I have used this answer. Somehow it worked but only in forward direction.
2: How to give Snap center to the particular item which is selected by the user?
For example: As shown in the image, if the user clicks on '15' then that item will come to the center. Same as if the user clicks on '07' then it should come to the center position.
I have implemented this demo. But it doesn't work on click on the item.
The code which I have done so far is as below:
Layout Manager:
final CenterZoomLayoutManager mLayoutManager = new CenterZoomLayoutManager(mContext,
CenterZoomLayoutManager.HORIZONTAL, false);// To get centered item zoom
recyclerview.setLayoutManager(mLayoutManager);
Adapter object:
mAdapter = new CustomAdapter(mContext, arrayList, new RecyclerViewClickListener() {
#Override
public void recyclerViewListClicked(View v, int position) {
}
});
recyclerview.setAdapter(mAdapter);
Any help is appreciated!
Thanks.
CarouselView may fulfill your requirements. Please check following GitHub links for the same.
https://android-arsenal.com/details/1/1481
https://github.com/nicklockwood/iCarousel
https://www.pocketmagic.net/a-3d-carousel-view-for-android/
https://github.com/clkasd/CarouselViewProject
How do I create a circular (endless) RecyclerView?
There is no way of making it infinite, but there is a way to make it
look like infinite.
in your adapter override getCount() to return something big like
Integer.MAX_VALUE:
#Override
public int getCount() {
return Integer.MAX_VALUE;
}
in getItem() and getView() modulo divide (%) position by real item
number:
#Override
public Fragment getItem(int position) {
int positionInList = position % fragmentList.size();
return fragmentList.get(positionInList);
}
at the end, set current item to something in the middle (or else, it
would be endless only in downward direction).
// scroll to middle item
recyclerView.getLayoutManager().scrollToPosition(Integer.MAX_VALUE / 2);
For snapping
use SnapHelper or scrollToPositionWithOffset, where offset is (width/2 - itemWidth/2)
I can use this library
You can solve your problem by personalizing this library. By selecting each item, you can use the ScrollToX function to navigate to that item.
https://github.com/mahdimoaz/RecyclerViewHorizontalCenterSelected
How can I make it so that in the recycleView there are differents size cards? (1x1, 1x2 and 2x1 where 1 is the card length)
enter image description here
You can create two view holders. One of them holds the two cards that are in the same row, the other holds the full row one. It would definitely look like the image you posted. For implementing the recycler view with multiple view holders check out this.
You can use GridLayoutManager with different span count.
Here is some example.
In activity:
//Initialize recyclerView and adapter before
GridLayoutManager layoutManager = new GridLayoutManager(this, 2);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(adapter);
layoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
#Override
public int getSpanSize(int position) {
if (adapter.isHeader(position)) {
//Returns span count 2 if method isHeader() returns true.
//You can use your own logic here.
return mLayoutManager.getSpanCount()
} else {
return 1;
}
}
}
});
And add this method to your adapter class:
public boolean isHeader(int position) {
return position == 0;//you can use some other logic in here
}