真正解决ScrollView 和 RecyclerView 嵌套问题

问题一:ScrollView嵌套RecyclerView显示不完全

    这个问题应该都遇到过,我之前就被这个问题搞的崩溃了,网上搜的解决方法都是重写LinearLayoutManager,有人说有效,但在我这没用,我也不知道那些方法是不是真的有效,但还是在最下边把这个方法贴出来吧,万一对你有用呢。

      真正解决我问题的是另一个方法,不用重写什么布局管理器,只要将嵌套在外层的ScrollView的宽、高均设置为match_parent,然后在ScrollView的布局中加入一句话(必须):

    android:fillViewport="true"

      然后在RecyclerView的外层再嵌套一个LinearLayout或RelativeLayout即可,这样RecyclerView就可以显示完整。别问我为什么,我也不懂。╮(╯3╰)╭

补充:其实现在直接用android.support.v4.widget.NestedScrollView替代ScrollView,并给RecyclerView设置.setNestedScrollingEnabled(false)属性即可解决

问题二:滑动冲突、滑动不流畅

        recyclerView.setHasFixedSize(true);

        recyclerView.setNestedScrollingEnabled(false);

问题三:嵌套布局不显示在顶部,直接显示RecyclerView 第一个item

        在Xml页面顶部位置的布局控件中加入两句代码:

        Android:focusable="true"
        android:focusableInTouchMode="true" 

        之前还写过一篇解决这类问题的文章:

        https://my.oschina.net/wanghz/blog/898256

        应该也可以,我没试。

 

附:重写的LinearLayoutManager布局管理器:

package com.wanghz.farver.widget;

import android.content.Context;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;

/**
 * Created by Wanghz on 2017/5/25.
 */
public class ScrollLinearLayoutManager extends LinearLayoutManager {

	private static final String TAG = ScrollLinearLayoutManager.class.getSimpleName();

	public ScrollLinearLayoutManager(Context context) {
		super(context);
	}

	public ScrollLinearLayoutManager(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);

		Log.i(TAG, "onMeasure called. \nwidthMode " + widthMode
				+ " \nheightMode " + heightSpec
				+ " \nwidthSize " + widthSize
				+ " \nheightSize " + heightSize
				+ " \ngetItemCount() " + getItemCount());

		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);//fix 动态添加时报IndexOutOfBoundsException

			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();
		} finally {
		}
	}
}

然后再在代码中添加:

        ScrollLinearLayoutManager linearLayoutManager = new ScrollLinearLayoutManager(this);  
        recyclerView.setNestedScrollingEnabled(false);  
        //设置布局管理器  
        recyclerView.setLayoutManager(linearLayoutManager);  

你们可以试试,反正对我没用。

转载于:https://my.oschina.net/wanghz/blog/908902

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值