通过重写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是正常的。