Changing number of columns in RecyclerView gridlayout

后端 未结 4 803
梦如初夏
梦如初夏 2020-12-08 16:44

I am trying to change the number of columns that appear in the recycler view (grid layout) based on the display size. However I couldn\'t figure out a proper way of achievin

相关标签:
4条回答
  • 2020-12-08 16:59
    public class VarColumnGridLayoutManager extends GridLayoutManager {
    
    private int minItemWidth;
    
    public VarColumnGridLayoutManager(Context context, int minItemWidth) {
        super(context, 1);
        this.minItemWidth = minItemWidth;
    }
    
    @Override
    public void onLayoutChildren(RecyclerView.Recycler recycler,
            RecyclerView.State state) {
        updateSpanCount();
        super.onLayoutChildren(recycler, state);
    }
    
    private void updateSpanCount() {
        int spanCount = getWidth() / minItemWidth;
        if (spanCount < 1) {
            spanCount = 1;
        }
        this.setSpanCount(spanCount);
    }}
    
    0 讨论(0)
  • 2020-12-08 16:59

    You could create a screen dependent resource file and load it. A booleans.xml in values-w820p folder for example. Or possibly just create a layout for large screens and be done with it.

    0 讨论(0)
  • 2020-12-08 17:05

    If you provide a fixed column width, you can extend RecyclerView and set the span count in onMeasure accordingly:

    public AutofitRecyclerView(Context context, AttributeSet attrs) {
      super(context, attrs);
    
      if (attrs != null) {
        // Read android:columnWidth from xml
        int[] attrsArray = {
            android.R.attr.columnWidth
        };
        TypedArray array = context.obtainStyledAttributes(attrs, attrsArray);
        columnWidth = array.getDimensionPixelSize(0, -1);
        array.recycle();
      }
    
      manager = new GridLayoutManager(getContext(), 1);
      setLayoutManager(manager);
    }
    
    protected void onMeasure(int widthSpec, int heightSpec) {
      super.onMeasure(widthSpec, heightSpec);
      if (columnWidth > 0) {
        int spanCount = Math.max(1, getMeasuredWidth() / columnWidth);
        manager.setSpanCount(spanCount);
      }
    }
    

    See my blog post for more info: http://blog.sqisland.com/2014/12/recyclerview-autofit-grid.html

    0 讨论(0)
  • 2020-12-08 17:19

    Here's my solution.

    public class ResponsiveGridLayoutManager extends GridLayoutManager {
        boolean hasSetupColumns;
        int columnWidthPx;
    
        public ResponsiveGridLayoutManager(Context context, int orientation,
            boolean reverseLayout, int columnWidthUnit, float columnWidth) {
    
            super(context, 1, orientation, reverseLayout);
    
            Resources r;
            if (context == null) {
                r = Resources.getSystem();
            } else {
                r = context.getResources();
            }
    
            float colWidthPx = TypedValue.applyDimension(columnWidthUnit,
                columnWidth, r.getDisplayMetrics());
    
            this.columnWidthPx = Math.round(colWidthPx);
        }
    
        public ResponsiveGridLayoutManager(Context context, AttributeSet attrs,
            int defStyleAttr, int defStyleRes) {
    
            super(context, attrs, defStyleAttr, defStyleRes);
            int[] requestedValues = {
                android.R.attr.columnWidth,
            };
    
            TypedArray a = context.obtainStyledAttributes(attrs, requestedValues);
            this.columnWidthPx = a.getDimensionPixelSize(0, -1);
            a.recycle();
        }
    
        @Override
        public int getWidth() {
            int width = super.getWidth();
            if (!hasSetupColumns && width > 0) {
                this.setSpanCount((int)Math.floor(width / this.columnWidthPx));
            }
    
            return width;
        }
    }
    

    You can use it with either XML:

    <android.support.v7.widget.RecyclerView
        android:id="@+id/recycler"
        android:scrollbars="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
    
        app:layoutManager="com.caff.localflix.ResponsiveGridLayoutManager"
        android:columnWidth="148dp" />
    

    Or Java:

    ResponsiveGridLayoutManager layoutManager = new ResponsiveGridLayoutManager(
        this,
        GridLayoutManager.VERTICAL,
        false,
        TypedValue.COMPLEX_UNIT_DIP,
        148f
    );
    
    0 讨论(0)
提交回复
热议问题