I have a RecyclerView and GridLayoutManager with 2 columns.
How can I force LayoutManager to be according with template on the first screenshot? Now I have result as on the 2th screenshot.
Need result:
Current result:
GridLayoutManager will use a grid, and you can set some span, but not different heights for different cells.
What you want is a StaggeredGridLayoutManager. This will just put the items on the screen if they fit, leading to your needed result. You can also change the reordering behavior, if you want to, by using setGapStrategy.
It's really easy. You have to add this manager to RecycleView:
recyclerView.setLayoutManager(new StaggeredGridLayoutManager(mColumnCount, 1));
in my case it's look like this:
Context context = view.getContext();
RecyclerView recyclerView = (RecyclerView) view;
if (mColumnCount <= 1) {
recyclerView.setLayoutManager(new LinearLayoutManager(context));
} else {
recyclerView.setLayoutManager(new StaggeredGridLayoutManager(mColumnCount, 1));
}
recyclerView.setAdapter(new MyItemRecyclerViewAdapter(DummyContent.ITEMS, mListener));
Related
I am new to android i have developed an application in which i have to display images horizontal view on single activity i have done using staggered recycleview but am getting like this.
But i want to design like this as part of the activity.
You can easily do that with GridLayoutManager. Use SpanSizeLookup to control your row/column . For your case you have to use HORIZONTAL orientation. SpanSizeLookup will help you to control your rows in each column in HORIZONTAL GridLayoutManager.
GridLayoutManager gridLayoutManager = new GridLayoutManager(getContext(), NUM_OF_ROW, LinearLayoutManager.HORIZONTAL, reverseOrder);
GridLayoutManager.SpanSizeLookup spanSizeLookup = new GridLayoutManager.SpanSizeLookup() {
#Override
public int getSpanSize(int position) {
// for position 0 use only one row. for this position it will take all rows
if (position == 0) {
return NUM_OF_ROW;
}
return 1;
}
};
Here is blog post about different Layout Manager implementation.
I have uploaded a repo on Github about different LayoutManager usage like LinearLayoutManager, GridLayoutManager, StaggeredGridLayoutManager and some advance RecyclerView usage like swipe, Drag and Drop. You can also check that
here is what i use for arranging items horizontally provided you're using RecyclerView:
int numberOfColumns = 3; //edit as you want pls
final GridLayoutManager gridLayoutManager = new GridLayoutManager(this.getContext(), numberOfColumns);
recyclerView.setLayoutManager(gridLayoutManager);
recyclerView.setAdapter(adapter);
I might be off your solution, perdon if so, but pasting some of your code might help better.
I need a recycler view with different number of columns in a row. For that I have used a gridlayout manager with dynamic span size. Here is my code:
rvSubCat.layoutManager = StaggeredGridLayoutManager(4, 1)
val viewTreeObserver = rvSubCat.getViewTreeObserver()
viewTreeObserver.addOnGlobalLayoutListener(ViewTreeObserver.OnGlobalLayoutListener { calculateSize() })
categoryAdapter = CategoryAdapter(categoryList, true, this)
rvSubCat.adapter = categoryAdapter
private fun calculateSize() {
val spanCount = Math.floor((rvSubCat.getWidth() / SizeUtils.dp2px(sColumnWidth.toFloat())).toDouble()).toInt()
(rvSubCat.getLayoutManager() as StaggeredGridLayoutManager).spanCount = spanCount
}
But the desired result is not good. It is fixing the number of columns in every row. I need the number of columns should depend upon the total width of the row items.
Need this (Desired Result):
Getting This
Best light weight library i use
compile 'com.xiaofeng.android:flowlayoutmanager:1.2.3.2'
Benifit is you dont need to change your existing code, you just need to change recyclerview's LayoutManager like
recyclerView.setLayoutManager(new FlowLayoutManager());
You are all set, Happy coding :)
Update You know already how to populate recycler view. But verify by following
private void setAdapter() {
recyclerView = (RecyclerView) fragment_view.findViewById(R.id.rv);
recyclerView.setLayoutManager(new FlowLayoutManager());
myRecyclerAdapter = new AdapterOrders(getActivity(), list);
recyclerView.setAdapter(myRecyclerAdapter);
}
Call myRecyclerAdapter.notifyDataSetChanged(); after list is change from any source.
What you need is flow Layout. I think these library will help you solve the purpose :
https://github.com/nex3z/FlowLayout
https://github.com/ApmeM/android-flowlayout
Adjusts according to size of texts. Hope this helps !
I've created a custom ItemDecoration for a RecyclerView that is using a GridLayoutManager. The ItemDecoration essentially ensures that equivalent spacing between all of the child views is applied within the RecyclerView:
The ItemDecoration is working exactly as I hoped it would and I think it looks great. However, I noticed that I need to add the ItemDecoration before I set the layout manager for my RecyclerView. My main question is: Why is that?
I'm working with some legacy code that uses a CursorLoader to pull RSS feeds from the web and display them to the end user. For whatever reason, the layout manager is being set in onLoadFinished():
#Override
public void onLoadFinished(Loader<Cursor> cursorLoader, Cursor cursor) {
Adapter adapter = new Adapter(cursor);
adapter.setHasStableIds(true);
mRecyclerView.setAdapter(adapter);
GridLayoutManager gridLayoutManager =
new GridLayoutManager(this, mColumnCount, GridLayoutManager.VERTICAL, false);
mRecyclerView.setLayoutManager(gridLayoutManager);
}
I noticed that if I add my ItemDecoration within onLoadFinished(), the margins between the items looks bigger than it really should:
#Override
public void onLoadFinished(Loader<Cursor> cursorLoader, Cursor cursor) {
Adapter adapter = new Adapter(cursor);
adapter.setHasStableIds(true);
mRecyclerView.setAdapter(adapter);
GridLayoutManager gridLayoutManager =
new GridLayoutManager(this, mColumnCount, GridLayoutManager.VERTICAL, false);
mRecyclerView.setLayoutManager(gridLayoutManager);
// Adding the custom ItemDecoration
EqualOffsetItemDecoration itemDecoration = new EqualOffsetItemDecoration(this, R.dimen.card_view_margin, mColumnCount);
mRecyclerView.addItemDecoration(itemDecoration);
}
The screenshot above shows far more margin than I was expecting since I'm only applying 8dps (the value of card_view_margin). However, if I add the ItemDecoration within onCreate(), then it appears as expected:
#Override
protected void onCreate(Bundle savedInstanceState) {
...
mRecyclerView = (RecyclerView) findViewById(R.id.recycler_view);
mColumnCount = getResources().getInteger(R.integer.list_column_count);
/*
In order to have equal spacing along the edges of the screen as well as between the
child views of the RecyclerView, an EqualOffsetItemDecoration is applied to the RecyclerView.
*/
EqualOffsetItemDecoration itemDecoration = new EqualOffsetItemDecoration(this, R.dimen.card_view_margin, mColumnCount);
mRecyclerView.addItemDecoration(itemDecoration);
...
}
...which is the case for the first screenshot. So why does this matter? Why do I need to add the ItemDecoration before applying a layout manager to my RecyclerView? I'm sure that this has something to do with the order in which things are executed under the hood. Any sort of explanation is greatly appreciated :)
FYI, in case anyone is interested in how I created my ItemDecoration, here it is:
https://github.com/mikepalarz/XYZReader/blob/master/app/src/main/java/com/example/xyzreader/ui/EqualOffsetItemDecoration.java
Interesting question, but I don't believe it matters if you set the layout manager before or after the item decoration. Both calls result in a request for layout.
I am going to guess that you are adding the decoration to the RecyclerView more than one time. Since decorations compound, you will see a greater gap with the decoration added two times (or more times) instead of just once.
I need to implement a list that has some card which scroll horizontally (scroll one item at a time like facebook friend suggestion list).
Use RecyclerView & set layout manager to that like this
recyclerView.setLayoutManager(new LinearLayoutManager(this) {
#Override
public boolean canScrollVertically() {
return false;
}
});
recyclerView.setAdapter(adapter);
I hope this will help you.
for set horizontal RecyclerView use :
LinearLayoutManager mLayoutManager = new LinearLayoutManager(Context, RecyclerView.HORIZONTAL, false);
mRecyclerView.setLayoutManager(mLayoutManager);
and for showing horizontal scrollBar in RecyclerView , in xml layout :
android:scrollbars="horizontal"
and with this line you can set custom scrollBar:
android:scrollbarThumbHorizontal="#drawable/recycler_scroll"
I want the user to be able to navigate to certain positions within a RecyclerView. I can determine the position of the items and when I use recycleView.smoothScrollToPosition() it scrolls to the correct item.
The problem is this item is at the bottom of the screen. How can I scroll so that the item appears at the top (it must be the first visible item).
Here is the code I use to setup the RecyclerView:
recyclerView = (RecyclerView)findViewById(R.id.recyclerview);
recyclerView.setHasFixedSize(false);
recyclerView.setAdapter(actionAdapter);
final LinearLayoutManager layoutManager = new LinearLayoutManager(InteractionTimelineActivity.this, LinearLayoutManager.VERTICAL, false);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setOnScrollListener(new RecyclerScrollListner());
And this is how I scroll:
if (recycleView != null) {
recycleView.smoothScrollToPosition(position + 1);
}
You have to calculate how many items fit on one screen and use that as offset when you scroll! You can use the methods findFirstCompletelyVisibleItemPosition() and findLastCompletelyVisibleItemPosition() of the LayoutManager to calculate the offset like this:
int offset = getLayoutManager()).findLastCompletelyVisibleItemPosition()
- getLayoutManager()).findFirstCompletelyVisibleItemPosition();
And once you have the offset you can scroll like this:
recycleView.smoothScrollToPosition(Math.min(position + offset + 1, adapter.getItemCount()));