GridLayoutManager - how to auto fit columns?

后端 未结 8 2050
野性不改
野性不改 2020-11-30 18:30

I have a RecyclerView with a GridLayoutManager that displays Card Views. I want the cards to rearrange according to the screen size (the Google Play app does this kind of th

8条回答
  •  刺人心
    刺人心 (楼主)
    2020-11-30 19:30

    I tried @Riten answer and worked funtastic!! But I wasn't happy with the hardcoded "180" So I modified to this:

        public class ColumnQty {
        private int width, height, remaining;
        private DisplayMetrics displayMetrics;
    
        public ColumnQty(Context context, int viewId) {
    
            View view = View.inflate(context, viewId, null);
            view.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
            width = view.getMeasuredWidth();
            height = view.getMeasuredHeight();
            displayMetrics = context.getResources().getDisplayMetrics();
        }
        public int calculateNoOfColumns() {
    
            int numberOfColumns = displayMetrics.widthPixels / width;
            remaining = displayMetrics.widthPixels - (numberOfColumns * width);
    //        System.out.println("\nRemaining\t" + remaining + "\nNumber Of Columns\t" + numberOfColumns);
            if (remaining / (2 * numberOfColumns) < 15) {
                numberOfColumns--;
                remaining = displayMetrics.widthPixels - (numberOfColumns * width);
            }
            return numberOfColumns;
        }
        public int calculateSpacing() {
    
            int numberOfColumns = calculateNoOfColumns();
    //        System.out.println("\nNumber Of Columns\t"+ numberOfColumns+"\nRemaining Space\t"+remaining+"\nSpacing\t"+remaining/(2*numberOfColumns)+"\nWidth\t"+width+"\nHeight\t"+height+"\nDisplay DPI\t"+displayMetrics.densityDpi+"\nDisplay Metrics Width\t"+displayMetrics.widthPixels);
            return remaining / (2 * numberOfColumns);
        }
    }
    

    Where "viewId" is the layout to be used as views in the RecyclerView like in R.layout.item_for_recycler

    Not sure though about the impact of View.inflate as I only use it to get the Width, nothing else.

    Then on the GridLayoutManager I do:

    GridLayoutManager gridLayoutManager = new GridLayoutManager(this, Utility.columnQty(this, R.layout.item_for_recycler));
    

    UPDATE: I added more lines to the code as I use it to get a minimum width spacing in the Grid. Calculate spacing:

    recyclerPatternsView.addItemDecoration(new GridSpacing(columnQty.calculateSpacing()));
    

    GridSpacing:

    public class GridSpacing extends RecyclerView.ItemDecoration {
        private final int spacing;
    
        public GridSpacing(int spacing) {
            this.spacing = spacing;
        }
    
        @Override
        public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
            outRect.left = spacing;
            outRect.right = spacing;
            outRect.bottom = spacing;
            outRect.top = spacing;
        }
    }
    

提交回复
热议问题