解决 RecyclerView 自适应高度

通过重写LinearLayoutManager来实现RecyclerView的自适应高度,具体代码如下:

public class MyLinearLayoutManager extends LinearLayoutManager {

    private int widthSpec;
    private int heightSpec;
    private int[] mMeasuredDimension = new int[2];

public MyLinearLayoutManager(Context context , int orientation , boolean reverseLayout) { super(context , orientation , reverseLayout) ; } @Override public void onLayoutChildren(RecyclerView.Recycler recycler , RecyclerView.State state) { super.onLayoutChildren(recycler , state) ; 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 width = 0 ; int height = 0 ; for ( int i = 0 ; i < getItemCount() ; i++) { if (getOrientation() == HORIZONTAL) { measureScrapChild(recycler , i , View.MeasureSpec. makeMeasureSpec(i , View.MeasureSpec. UNSPECIFIED) , heightSpec , mMeasuredDimension) ; width = width + mMeasuredDimension[ 0] ; if (i == 0) { height = mMeasuredDimension[ 1] ; } } else { measureScrapChild(recycler , i , widthSpec , View.MeasureSpec. makeMeasureSpec(i , View.MeasureSpec. UNSPECIFIED) , mMeasuredDimension) ; height = height + mMeasuredDimension[ 1] ; if (i == 0) { width = mMeasuredDimension[ 0] ; } } } switch (widthMode) { case View.MeasureSpec. EXACTLY: width = widthSize ; case View.MeasureSpec. AT_MOST: case View.MeasureSpec. UNSPECIFIED: } switch (heightMode) { case View.MeasureSpec. EXACTLY: height = heightSize ; case View.MeasureSpec. AT_MOST: case View.MeasureSpec. UNSPECIFIED: } Log. d( TAG , "onMeasure: " + width + " " + height) ; setMeasuredDimension(width , height) ; } @Override public void onMeasure(RecyclerView.Recycler recycler , RecyclerView.State state , int widthSpec , int heightSpec) { this. widthSpec = widthSpec ; this. heightSpec = heightSpec ; } private void measureScrapChild(RecyclerView.Recycler recycler , int position , int widthSpec , int heightSpec , int[] measuredDimension) { try{ View view = recycler.getViewForPosition(position) ; recycler.bindViewToPosition(view , 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 ; recycler.recycleView(view) ; } } catch (Exception e) { e.printStackTrace() ; } }} 网上部分代码会把设置高度的方法写在onMeasure中,但是部分编译器版本中onMeasure里的变量recycler是有问题的,在View view = recycler.getViewForPosition(position)会出现错误,具体解决方法是把设置高度的方法写在onLayoutChildren中,onLayoutChildren的recycler是正常的。

你可能感兴趣的:(android)