17

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
  • 5,408
  • 15
  • 61
  • 104
  • Still don't understand what exactly you want?? – Arati PAtel Jan 04 '17 at 07:05
  • can you post your xml layout? Did you used `columnSpan` and `columnWeight`? – Hugo Gresse Jan 04 '17 at 09:07
  • @aratikyada I put some more explanation and a repo you can clone to reproduce this behavior and maybe better understanding what I mean. – MHogge Jan 04 '17 at 09:17
  • @HugoGresse I posted my XML layout but no I don't use columnSpan or columnWeight, but this isn't necessary as I want every column having a different width. Or am I wrong? – MHogge Jan 04 '17 at 09:17
  • for me you should have a predefined grid. As we do for web, a page is splitted in 12 "cells" or grid. And you align your element on this grid. So you may cut your layout and use columnWeight. Let me know if it solve the issue. Did you find anything in the doc? – Hugo Gresse Jan 04 '17 at 09:24
  • Check if this article might help you : http://blog.sqisland.com/2014/12/recyclerview-autofit-grid.html – Hristo Stoyanov Jan 04 '17 at 09:39
  • why would you wrap the recyclerview in horizontalScrollView? – Kosh Jan 04 '17 at 09:50
  • @HristoStoyanov I already read this article but the class provided here doesn't seem to help me (or maybe I'm not doing it the good way). – MHogge Jan 04 '17 at 09:53
  • @k0sh I'm dynamically generating some kind of 2D table (like excel but simplier) that doesn't have a fixed number of rows and columns and so those table can have 10 or + columns and I doesn't want to be limited with the device screen width, it should be scrollable in both ways (verically & horizontally). – MHogge Jan 04 '17 at 09:55
  • then you should be using nested recyclerviews instead of horizontalScrollView. could you confirm that the spaces exists without wrapping RC in HSV? you can use android:orientation="horizontal" in the RC tag in xml if you haven't defined that in ur code – Kosh Jan 04 '17 at 09:58
  • I already fix my issue but for those who are facing the same problem, maybe this library can help too : https://github.com/zhouchaoyuan/excelPanel – MHogge Feb 17 '17 at 09:47

1 Answers1

8

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));
Suresh Kumar
  • 2,014
  • 3
  • 19
  • 32
  • 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 Jan 04 '17 at 14:33
  • And if I don't find any solution, I will accept yours as it resolve the problem initially described. – MHogge Jan 04 '17 at 14:34
  • Couldn't able to get what you are expecting. Can you explain your expectation clearly? – Suresh Kumar Jan 05 '17 at 06:18
  • 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 : http://img11.hostingpics.net/pics/663448exemplestatisticstableexcel.png. My expectation is to create this kind of table using RV. – MHogge Jan 05 '17 at 08:28
  • 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. – MHogge Jan 05 '17 at 08:31
  • Works. Can you put the "Edit" to the top of the answer? People wont see the new answer until they scroll down. – Ali Kazi Jul 28 '17 at 05:44
  • 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? – User Jun 14 '18 at 07:44
  • The line grid.setHasFixedSize(true); calculates the child size and sets the max size to all its child. – Suresh Kumar Jun 16 '18 at 20:48
  • `LinearLayoutManager.HORIZONTAL` - what are you doing? I need table which is vertically scrollable with dynamic rows but fixed columns – user924 Jan 03 '20 at 16:03
  • @user924 try using `StaggeredGridLayoutManager(noOfColumn, VERTICAL)`. – Suresh Kumar Jan 06 '20 at 09:51