Variable number of columns in GridLayoutManager
Asked Answered
C

3

19

I wanted to display variable number of columns in a row of GridLayoutManager while using RecyclerView. The number of columns to be displayed depends on the size of the column's TextView.

I don't know the column width as the text is being dynamically put in it.

Can anyone help? StaggeredGridLayoutManager is not solving my purpose as it customizes the height but takes fixed number of columns.

Chlorpromazine answered 24/9, 2015 at 14:3 Comment(0)
P
37

Take a look at the setSpanSizeLookup method of the GridLayoutManager. It lets you specify the span size for specific positions of your RecyclerView. So maybe you could use it to fit with your requirements for the variable column number.

Edit:

GridLayoutManager manager = new GridLayoutManager(context, 2); // MAX NUMBER OF SPACES
manager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
    @Override
    public int getSpanSize(int position) {
        if (position == 1 || position == 6) {
            return 2; // ITEMS AT POSITION 1 AND 6 OCCUPY 2 SPACES
        } else {
            return 1; // OTHER ITEMS OCCUPY ONLY A SINGLE SPACE
        }
    }
});

When using this sort of layout manager your RecyclerView should look like this:

+---+---+
| 0 |   |
+---+---+
|   1   |
+---+---+
| 2 | 3 |
+---+---+
| 4 | 5 |
+---+---+
|   6   |
+---+---+

(only boxes with numbers represent items of your RecyclerView, other boxes are just empty spaces)

Phosphorescent answered 24/9, 2015 at 14:11 Comment(3)
Yes i did but couldnt understand the its implememtation. Can you post an example/Chlorpromazine
I added an example to my answerPhosphorescent
very nice explanation sirRuffner
A
6

If you want to make a variation like: 4 columns, 5 columns, 6 columns... You can get the MMC (minimum multiple common) between this numbers (60) and set the GridLayoutManager:


    GridLayoutManager manager = new GridLayoutManager(context, 60); // set the grid with the MMC
    manager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
        @Override
        public int getSpanSize(int position) {
            return 12; // 60/12 = 5 Columns
        }
    });
Then you could return 10, 12 or 15 for 6, 5 and 4 columns on getSpanSize()
Avrom answered 11/8, 2016 at 21:21 Comment(0)
U
1

You can use the span based on calculating the width.

     public class AutoFitGridLayoutManager extends GridLayoutManager {
                    private boolean columnWidthChanged = true;
                    Context context;

                    public AutoFitGridLayoutManager(Context context) {
                        super(context, 1);
                        this.context = context;
                        setColumnWidth();
                    }

                    public void setColumnWidth() {
                            columnWidthChanged = true;
                    }

                    @Override
                    public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
                        if (columnWidthChanged) {
                          
                            //int spanCount = Math.max(1, totalSpace / columnWidth);
                            //setSpanCount(spanCount);
                            setSpanCount(Utils.calculateNoOfColumns(context));
                            columnWidthChanged = false;
                        }
                        super.onLayoutChildren(recycler, state);
                    }
                }

For calculating the columns you can use this method:

        public static int calculateNoOfColumns(Context context) {

                DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
                float dpWidth = displayMetrics.widthPixels / displayMetrics.density;
                int scalingFactor = 200; // You can vary the value held by the scalingFactor
                // variable. The smaller it is the more no. of columns you can display, and the
                // larger the value the less no. of columns will be calculated. It is the scaling
                // factor to tweak to your needs.
                int columnCount = (int) (dpWidth / scalingFactor);
                return (columnCount>=2?columnCount:2); // if column no. is less than 2, we still display 2 columns
}
Unfurl answered 20/10, 2020 at 16:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.