GridLayoutManager - column width wrap its own largest child

18.6k views Asked by At

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 !

1

There are 1 answers

10
Suresh Kumar On BEST ANSWER

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));