GridLayoutManager高度无法设置为WRAP_CONTENT(Vertical情况下)

来源:互联网 发布:四川禄宏微交易 知乎 编辑:程序博客网 时间:2024/05/21 09:49

     RecyclerView相信大家都不会陌生,作为ListView的替代控件,为大家提供了很多方便,在使用的时候我们会发现一个setLayoutManager这样一个方法,他的参数可以是LinearLayoutManager,GridLayoutManager以及特别酷炫的StaggeredGridLayoutManager,至于区别呢,大家自己动手,今天主要记录一下GridLayoutManager这个类。

  GridLayoutManager主要是实现GridView这样的效果的,用着用着你会发现一个坑,那就是这个家伙高度无法设置为Wrap_content,就是说无论有几个子View高度都是一样的(Vertical情况下),都是MATCH_PARENT,效果如下:


   解决的方式是写个子类继承GridLayoutManager,如下:

class WrappableGridLayoutManager extends GridLayoutManager {        public WrappableGridLayoutManager(Context context, int spanCount) {            super(context, spanCount);        }        private int[] mMeasuredDimension = new int[2];        @Override        public boolean canScrollVertically() {            return false;        }        @Override        public void onMeasure(RecyclerView.Recycler recycler, RecyclerView.State state, int widthSpec, int heightSpec) {            final int widthMode = View.MeasureSpec.getMode(widthSpec);            final int heightMode = View.MeasureSpec.getMode(heightSpec);            final int widthSize = View.MeasureSpec.getSize(widthSpec);            final int heightSize = View.MeasureSpec.getSize(heightSpec);            int spanWidth = 0;            int spanHeight = 0;            int viewWidth = 0;            int viewHeight = 0;            int spanCount = getSpanCount();            for (int i = 0; i < getItemCount(); i++) {                measureScrapChild(recycler, i, View.MeasureSpec.makeMeasureSpec(i, View.MeasureSpec.UNSPECIFIED), View.MeasureSpec.makeMeasureSpec(i, View.MeasureSpec.UNSPECIFIED), mMeasuredDimension);                if(i%spanCount==0){                    spanWidth=mMeasuredDimension[0];                    spanHeight=mMeasuredDimension[1];                }else{                    if(getOrientation()==VERTICAL){                        spanWidth+=mMeasuredDimension[0];                        spanHeight=Math.max(spanHeight,mMeasuredDimension[1]);                    }else{                        spanWidth=Math.max(spanWidth,mMeasuredDimension[0]);                        spanHeight+=mMeasuredDimension[1];                    }                }                if(i%spanCount==spanCount-1||i==getItemCount()-1){                    if(getOrientation()==VERTICAL){                        viewWidth=Math.max(viewWidth,spanWidth);                        viewHeight+=spanHeight;                    }else{                        viewWidth+=spanWidth;                        viewHeight=Math.max(viewHeight,spanHeight);                    }                }            }            int finalHeight;            int finalWidth;            switch (widthMode){                case View.MeasureSpec.EXACTLY:                    finalWidth=widthSize;                    break;                case View.MeasureSpec.AT_MOST:                    finalWidth=Math.min(widthSize,viewWidth);                    break;                case View.MeasureSpec.UNSPECIFIED:                    finalWidth=viewWidth;                    break;                default:                    finalWidth=widthSize;                    break;            }            switch (heightMode){                case View.MeasureSpec.EXACTLY:                    finalHeight=heightSize;                    break;                case View.MeasureSpec.AT_MOST:                    finalHeight=Math.min(heightSize,viewHeight);                    break;                case View.MeasureSpec.UNSPECIFIED:                    finalHeight=viewHeight;                    break;                default:                    finalHeight=heightSize;                    break;            }            setMeasuredDimension(finalWidth,finalHeight);        }        private void measureScrapChild(RecyclerView.Recycler recycler, int position, int widthSpec, int heightSpec, int[] measuredDimension) {            View view = recycler.getViewForPosition(position);            if (view != null) {                RecyclerView.LayoutParams p = (RecyclerView.LayoutParams) view.getLayoutParams();                int childWidthSpec = ViewGroup.getChildMeasureSpec(widthSpec,                        getPaddingLeft() + getPaddingRight(), p.width);                int childHeightSpec = ViewGroup.getChildMeasureSpec(heightSpec,                        getPaddingTop() + getPaddingBottom(), p.height);                view.measure(childWidthSpec, childHeightSpec);                measuredDimension[0] = view.getMeasuredWidth() + p.leftMargin + p.rightMargin;                measuredDimension[1] = view.getMeasuredHeight() + p.bottomMargin + p.topMargin;                Rect decoratorRect=new Rect();                calculateItemDecorationsForChild(view,decoratorRect);                measuredDimension[0]+=decoratorRect.left;                measuredDimension[0]+=decoratorRect.right;                measuredDimension[1]+=decoratorRect.top;                measuredDimension[1]+=decoratorRect.bottom;                recycler.recycleView(view);            }        }    }

使用上述的类之后呢,效果就是
当然,我使用了addItemDecotation方法,这个就不多说了。打个广告http://stay4it.com/,大神带你飞,不喜勿喷。

0 0
原创粉丝点击