GridLayoutManager - column width wrap its own largest child

16,775

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));
Share:
16,775
MHogge
Author by

MHogge

Updated on June 14, 2022

Comments

  • MHogge
    MHogge about 2 years

    I got a RecyclerView inside an HorizontalScrollView and I want it to use a GridLayoutManager. 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 :

    enter image description here

    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.

    enter image description here

    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
    MHogge over 7 years
    This 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
    MHogge over 7 years
    And if I don't find any solution, I will accept yours as it resolve the problem initially described.
  • Suresh Kumar
    Suresh Kumar over 7 years
    Couldn't able to get what you are expecting. Can you explain your expectation clearly?
  • MHogge
    MHogge over 7 years
    I'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
    MHogge over 7 years
    If 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
    Ali Kazi almost 7 years
    Works. Can you put the "Edit" to the top of the answer? People wont see the new answer until they scroll down.
  • User
    User about 6 years
    Can 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
    Suresh Kumar about 6 years
    The line grid.setHasFixedSize(true); calculates the child size and sets the max size to all its child.
  • user924
    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
    Suresh Kumar over 4 years
    @user924 try using StaggeredGridLayoutManager(noOfColumn, VERTICAL).