原本的布局,下拉刷新嵌套recycleView(ListView也适用),布局是正常的但是在recycleView外层加了scrollView之后出现了recycleView数据显示不全的问题(本来有三条但是只显示1条)
xml布局:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/color_f4f7f9"
android:orientation="vertical">
<!--刷新-->
<com.sinldo.netHospital.view.PullDownToRefreshLayout
android:id="@+id/refreshLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="@dimen/dp_60">
<com.sinldo.netHospital.view.PullDownHeader
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<!--嵌套ScrollView-->
<ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:id="@+id/ll_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
.....
<!--再嵌套 RecyclerView-->
<com.sinldo.netHospital.view.MyRecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/tv_see_and_reply" />
</LinearLayout>
</ScrollView>
<com.sinldo.netHospital.view.PullDownFooter
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</com.sinldo.netHospital.view.PullDownToRefreshLayout>
代码:
@BindView(id = R.id.refreshLayout) private PullDownToRefreshLayout mRefreshLayout;//刷新 PullDownToRefreshLayout 在项目中用的是第三方 @BindView(id = R.id.recyclerView) private RecyclerView mRecyclerView;//回复列表 代码: mAdapter = new NoticeApplyAdapter(mDatas); mRecyclerView.setLayoutManager(new FullyLinearLayoutManager(this));//FullyLinearLayoutManager自定义布局 mRecyclerView.addItemDecoration(new RecycleViewDivider(this, LinearLayoutManager.HORIZONTAL)); mRecyclerView.setFocusable(false); mRecyclerView.setAdapter(mAdapter); mRecyclerView.setNestedScrollingEnabled(false); mRefreshLayout.setOnRefreshListener(this); mRefreshLayout.setOnLoadmoreListener(this);
解决刷新嵌套recycle时的冲突问题 FullyLinearLayoutManager(this)); mRecyclerView.setNestedScrollingEnabled(false);
FullyLinearLayoutManager代码如下:
public class FullyLinearLayoutManager extends LinearLayoutManager {
public FullyLinearLayoutManager(Context context) {
super(context);
}
public FullyLinearLayoutManager(Context context, int orientation, boolean reverseLayout) {
super(context, orientation, reverseLayout);
}
private int[] mMeasuredDimension = new int[2];
@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 width = 0;
int height = 0;
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 (getOrientation() == HORIZONTAL) {
width = width + mMeasuredDimension[0];
if (i == 0) {
height = mMeasuredDimension[1];
}
} else {
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:
}
setMeasuredDimension(width, height);
}
private void measureScrapChild(RecyclerView.Recycler recycler, int position, int widthSpec, int heightSpec, int[] measuredDimension) {
try {
View view = recycler.getViewForPosition(0);
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) {
} finally {
}
}
}
然后需求变更,这个页面部分内容显示超长,需要在本页面嵌套一层scrollView
但是,嵌套完成之后,发现,recycleView的内容显示不全,那么怎么办呢?
后来想到给recycleView添加一个高度试试,添加了高度之后果然成功了,所有item的数据都能显示完全了,但是重新定义高度有点麻烦,就想着既然都自定义视图了,干脆在定义recyclerView不就得了,代码如下:
/**
* 测量recyclerView的高度,并给其设置值,为了解决刷新嵌套scrollView中嵌套recycleView时候,recycle数据显示不全的问题
*/
public class MyRecyclerView extends RecyclerView {
public MyRecyclerView(Context context) {
super(context);
}
public MyRecyclerView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public MyRecyclerView(Context context, @Nullable AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
/**
* 改变高度 其中onMeasure函数决定了组件显示的高度与宽度;
* makeMeasureSpec函数中第一个函数决定布局空间的大小,第二个参数是布局模式
* MeasureSpec.AT_MOST的意思就是子控件需要多大的控件就扩展到多大的空间
* 之后在ScrollView中添加这个组件就OK了,同样的道理,ListView也适用。
*/
@Override
protected void onMeasure(int widthSpec, int heightSpec) {
int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,
MeasureSpec.AT_MOST);
super.onMeasure(widthSpec, expandSpec);
}
}
布局中:把recycleView改为MyRecyclerView即可
<com.sinldo.netHospital.view.MyRecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/tv_see_and_reply" />
现在所有的item已经全部显示出来了,但是还有一个小问题,就是进入该页面后焦点会首先停留在recycleView的顶端,需要在代码中设置参数:
mRecyclerView.setFocusable(false);
总结:出现以上原因是因为没有给recycleView添加高度导致的,最快的判断方法,直接给recycleView设置一个固定的值,看看数据是否显示完全.
至此 , 完成!!