前言
使用Recyclerview作为子布局时,高度设置为wrap_content,如果禁止了Recyclerview的滚动,那么它的高度应当是其里面子项的高度之和,而将其嵌入到ScrollView中时,当子项高度之和大于ScrollView原本的高度时,则获取的高度则为ScrollView的高度,使Recyclerview显示不全。
解决方法
由于将Recyclerview的高度设置为wrap_content,因此测量高度的时候是使用AT_MOST模式(这个也就是父组件能够给出的最大的空间,当前组件的长或宽最大只能为这么大,当然也可以比这个小),在这个模式下,测量的高度为父布局和子布局二者中高度小的那个,当Recyclerview的子项高度之和比父view的高度小时,则Recyclerview的高度为子项高度之和,当Recyclerview的子项高度之和比父view的高度大时,则使用的是父view的高度,因此会出现Recyclerview子项显示不全的情况。
而针对该情况,我们需要重写Recyclerview的onMeasure函数,使Recyclerview在测量时获取父布局的高度最大值变得更大
一个int类型我们知道有32位。而view的测量模式有三种,分别是MeasureSpec.UNSPECIFIED 不确定值,MeasureSpec.AT_MOST 最大值,MeasureSpec.EXACTLY 完全准确值。要表示三种状态,至少得2位二进制位。于是系统采用了最高的2位表示模式。如图:
后面30位代表的是组件的大小,因此可以将其全都置为1,也就是值为Integer.MAX_VALUE >> 2(30个1),因此无论Recyclerview的子项高度和多大都不可能比这个大,所以Recyclerview测量得到的高度就为其子项之和的高度
重写的方法如下
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, expandSpec);
}
如此便可以解决Recyclerview嵌套在ScrollView中显示子项不全的问题