GridLayoutManager - column width wrap its own largest child
You don't need to put your RecyclerView in HorizontalScrollView. See the code below.
public class MainActivity extends AppCompatActivity {
String[] list = new String[]{"Some text goes here", "Some small", "text", "goes here", "Some", "very large text", "goes here",
"Some text goes here", "Some small", "text", "goes here", "Some", "very large text", "goes here"};
RecyclerView grid;
GridAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
grid = (RecyclerView)findViewById(R.id.grid);
grid.setLayoutManager(new GridLayoutManager(this, 2, LinearLayoutManager.HORIZONTAL, false));
grid.setHasFixedSize(true);
adapter = new GridAdapter(list);
grid.setAdapter(adapter);
}
}
Adapter class
public class GridAdapter extends RecyclerView.Adapter<GridAdapter.ViewHolder>{
String[] mList;
public GridAdapter(String[] list) {
mList = list;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.row, parent, false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.bind(mList[position]);
}
@Override
public int getItemCount() {
return mList.length;
}
public class ViewHolder extends RecyclerView.ViewHolder {
TextView textView;
public ViewHolder(View itemView) {
super(itemView);
textView = (TextView)itemView.findViewById(R.id.text);
}
public void bind(String s) {
textView.setText(s);
}
}
}
row.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="wrap_content"
android:layout_height="match_parent"
android:padding="10dp">
<TextView android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="cab.suresh.gridlayoutexample.MainActivity">
<android.support.v7.widget.RecyclerView
android:id="@+id/grid"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</RelativeLayout>
Edit Place your RecyclerView inside NestedScrollView like this
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbars="none">
<android.support.v7.widget.RecyclerView
android:id="@+id/grid"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</android.support.v4.widget.NestedScrollView>
and set your number of spanCount like this
spanCount = 8;
grid.setLayoutManager(new GridLayoutManager(this, spanCount, LinearLayoutManager.HORIZONTAL, false));
MHogge
Updated on June 14, 2022Comments
-
MHogge about 2 years
I got a
RecyclerView
inside anHorizontalScrollView
and I want it to use aGridLayoutManager
. This is ok but one thing still bother me, the width of every columns are the same (based on the largest cell width I suppose?). Isn't it possible to wrap width of columns to match the largest cell of this specific column?It should look to something like this :
Where the orange part is the part taken by the cell's view.
EDIT
We asked me to clarify what I expect. An example is better than words, here you can see a screenshot of a RecyclerView with GridLayoutManager. Each item is a simple TextView containing randomly a text between 10 & 40 characters. The RecyclerView is inside an HorizontalScrollView as said before. We can see that every columns have the same width, despite the fact that no items in this column may fulfill the entire width. What I would like is to remove those useless empty space and having columns with different sizes with each column matching the width of its own largest child.
If you want to test this behavior, you may clone this repo I uploaded on Github : https://github.com/ShargotthDev/TestGrid
As asked, here is my XML layout (very basic) :
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent"> <HorizontalScrollView android:id="@+id/gameplay_hotizontalScroll_ScrollView" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_marginTop="70dp"> <android.support.v7.widget.RecyclerView android:layout_width="wrap_content" android:layout_height="match_parent" android:id="@+id/recycler_view" /> </HorizontalScrollView> </RelativeLayout>
EDIT 2
I should have mentioned that some of the cells may have a span size > 1 and the LayoutManager should be vertical so that those cells take more places horizontally and not vertically (don't know if I'm making myself understandable).
Thank's for your time !
-
MHogge over 7 yearsThis is really nice and it in fact answer the question. But I should have be more precised, the 2D table I'm generating with this RecyclerView/ScrollView combination may have cells with a spanSize > 1 but because your solution needs to have the LayoutManager set Horizontally, a cell with spanSize > 1 doesn't look as it look with a vertical LayoutManager. (Plus the fact that I would need to reorganize the way my dataset is created, but this isn't impossible). PS: I won't go back without accepting an answer if it really resolve my problem, don't worry.
-
MHogge over 7 yearsAnd if I don't find any solution, I will accept yours as it resolve the problem initially described.
-
Suresh Kumar over 7 yearsCouldn't able to get what you are expecting. Can you explain your expectation clearly?
-
MHogge over 7 yearsI'll try to be clear. What I want is to generate something called "Statistics Table". Those tables may have any number of rows and any number of columns. I first handle it with a TableLayout and it was working fine for small table but was taking too much time to inflate when it comes to table with lot of rows/columns. This is why I started to generate my tables using RecyclerView. An exemple of how a "Statistics Table" should look like is available on this link : img11.hostingpics.net/pics/…. My expectation is to create this kind of table using RV.
-
MHogge over 7 yearsIf I'm using ScrollView/RV combination is because the number of rows and columns may be really a lot (for examples 500 rows with 15 columns) and so the table should be scrollable the both way.
-
Ali Kazi almost 7 yearsWorks. Can you put the "Edit" to the top of the answer? People wont see the new answer until they scroll down.
-
User about 6 yearsCan you explain how this solves the problem described in the question? What exactly causes the grid layout manager to wrap around the largest child?
-
Suresh Kumar about 6 yearsThe line grid.setHasFixedSize(true); calculates the child size and sets the max size to all its child.
-
user924 over 4 years
LinearLayoutManager.HORIZONTAL
- what are you doing? I need table which is vertically scrollable with dynamic rows but fixed columns -
Suresh Kumar over 4 years@user924 try using
StaggeredGridLayoutManager(noOfColumn, VERTICAL)
.