NestedScrollView和ScrollView常见问题总结

文章目录

    • NestedScrollView和ScrollView常见问题总结
      • 1、NestedScrollView嵌套常见问题
      • 2、滑动冲突
      • 3、ScrollView包裹viewPager高度自适应(不推荐这么嵌套):
      • 4、根据ScrollView子View的高度,动态显示操作栏的位置:
      • 5、监听ScrollView滑动到底部,加载数据
      • 综合使用:

NestedScrollView和ScrollView常见问题总结

1、NestedScrollView嵌套常见问题

去除ScrollView滑动到顶部/底部 水波纹效果:
android:overScrollMode="never"
去除ScrollView滚动条:
android:scrollbars="none"
RecyclerView在ScrollView中高度显示不完整:
android:fillViewport="true"
//设置默认滚动到顶部
scrollView.post(new Runnable() {
	@Override
	public void run() {
	 scrollView.fullScroll(ScrollView.FOCUS_UP);
	}
});

//设置默认滚动到底部
scrollView.post(new Runnable() {
	@Override
	public void run() {
	 scrollView.fullScroll(ScrollView.FOCUS_DOWN);
	}
});

//监听ScrollView,滚动时软键盘自动隐藏
scrollView = (ScrollView) view.findViewById(R.id.scrollView);
scrollView.setOnTouchListener(new View.OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_MOVE) {
            ((InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE)).hideSoftInputFromWindow(getActivity().getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
        }
    return false;
    }
});

2、滑动冲突

2.1、滑动不流畅

解决方法一:嵌套滑动不激活。
mRecycleView.setNestedScrollingEnable(false);

解决办法二:
 LinearLayoutManager layoutManager = new LinearLayoutManager(getContext());
        recyclerView.setLayoutManager(layoutManager);
        recyclerView.setHasFixedSize(true);//
        recyclerView.setNestedScrollingEnabled(false);//
        layoutManager.setSmoothScrollbarEnabled(true);//
        layoutManager.setAutoMeasureEnabled(true);//

2.2、当NestedScrollView嵌套RecycleView布局由Fragment管理,Fragment切换时会自动滑动到ReycleView的顶部。

解决方法一:
在NestedScrollView唯一子布局中加入 android:descendantFocusability=“blocksDescendants”

android:descendantFocusability 有三个属性:
	beforeDescendants:viewgroup会优先其子类控件而获取到焦点
	afterDescendants:viewgroup只有当其子类控件不需要获取焦点时才获取焦点
	blocksDescendants:viewgroup会覆盖子类控件而直接获得焦点

解决方法二:
recyclerView.setFocusable(false);

2.3、NestedScrollView嵌套EditText,导致EditText滑动冲突

2.4、 一个内容很长的布局, 加了scrollview会自动滚动到底部的问题

解决:找到scrollview里的其中一个子控件

mTitle.setFocusable(true);
mTitle.setFocusableInTouchMode(true);
mTitle.requestFocus();

2.5、 NestedScrollView与AppBarLayout配合使用时,视图会重叠

 NestedScrollView与AppBarLayout配合使用时,NestedScrollView属性必须设置layout_behavior值,
 如果要使NestedScrollView与AppBarLayout实现联动,那前者的layout_behavior属性一定要设置和
 后者的所有根子布局的layout_scrollFlags属性一定都要设置!

2.6、scrollView 嵌套 RecyclerView 显示时会滚动到RecyclerView第一项

1.recyclerView去除焦点
	recyclerview.setFocusableInTouchMode(false);
	recyclerview.requestFocus();

2.让scrollView 或者 recyclerView顶端的某个控件获取焦点
	ll_top.setFocusableInTouchMode(true);  
	ll_top.requestFocus();

2.7、RecyclerView嵌套RecyclerView情况下,子列表抢占焦点,导致自动滚动、位移的问题:

方法:在最外层的RecyclerView的 直属父布局(不一定是根布局)添加以下属性:

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

2.8、NestedScrolView嵌套RecyclerView滑动到底部,Item第一次无法点击:

原因:在快速滑动到顶部和底部之后,NestedScrolView在一段时间内还处于 Fling 状态;
修复:RecyclerView添加以下属性:

// setNestedScrollingEnabled:是否允许嵌套滑动
android:nestedScrollingEnabled="false"

注意:这种做法只适合RecyclerView数据不多的情况;因为禁止滑动会使RecyclerView失去了复用Item的意义;

2.9、NestedScrollView嵌套RecyclerView为解决滑动冲突通常为RecyclerView设置setNestedScrollingEnabled(false),这样解决了滑动冲突,但是导致RecyclerView复用回收机制失效,RecyclerView会一次性创建并加载所有item,数据量少的情况可以忽略不复用的问题,数据量多会导致页面卡顿严重。

解决方法:
一、RecyclerView设置固定高度,setNestedScrollingEnabled(true)。RecyclerView可以复用但是会出现滑动冲突问题。
二、去掉NestedScrollView,将RecyclerView作为最外层布局,其他布局作为RecyclerView的HeadView或FooterView。
三、使用CoordinatorLayout嵌套RecyclerView,实现页面滑动。CoordinatorLayout嵌套RecyclerView会出现滑动抖动现象。

3、ScrollView包裹viewPager高度自适应(不推荐这么嵌套):

当Android的NestedScrollView/ScrollView这类滚动View包裹ViewPager时候,ViewPager中的Fragment包含的又是一系列高度值不固定的View如RecyclerView等等,就会造成ViewPager高度无法自适应子Fragment里面的View的高度。

解决方法其中之一就是重新改造ViewPager,让其能自动适应子Fragment里面的View高度,改造后的AutofitHeightViewPager:

Android NestedScrollView/ScrollView包裹ViewPager自适应高度

4、根据ScrollView子View的高度,动态显示操作栏的位置:

a、如果子View大于一屏,就底部悬停;
b、如果子View小于一屏,就不悬停,紧跟上面的View;
NestedScrollView和ScrollView常见问题总结_第1张图片

nViewDataBinding.rvImage.viewTreeObserver.addOnGlobalLayoutListener {
    LegoLog.d("加载完成时回调:onGlobalLayout")
    if (nViewModel.imageList.value.isNotEmpty() || nViewModel.fileList.value.isNotEmpty()) {
        refreshCanScroll()

        nViewDataBinding.scrollView.post {
            //将ScrollView滚动到底部
            nViewDataBinding.scrollView.fullScroll(View.FOCUS_DOWN)
        }
    } else {
        nViewModel.bottomFlag.set(false)
    }
}

//判断子View是否超过屏幕高度
private fun refreshCanScroll() {
    //childView是scrollview里包含的Linearlayout容器
    val childView = nViewDataBinding.scrollView.getChildAt(0)
    if (childView.height - nViewDataBinding.scrollView.height > 0) {
        LegoLog.d("可滚动")
        nViewModel.bottomFlag.set(true)
    } else {
        LegoLog.d("不可滚动")
        nViewModel.bottomFlag.set(false)
    }
}

5、监听ScrollView滑动到底部,加载数据

有时候我们想让在ScrollView滑动到底部的时候去做一些事情,但是scrollview并没有直接提供这样的方法,此时我们可以通过简单的继承一下ScrollView,为ScrollView滑动到底部设置一下监听:

public class ScrollBottomScrollView extends ScrollView {
	private OnScrollBottomListener listener;
	private int calCount;
	
	public interface OnScrollBottomListener {
	    void scrollToBottom();
	}
	
	public void onScrollViewScrollToBottom(OnScrollBottomListener l) {
	    listener = l;
	}
	
	public void unRegisterOnScrollViewScrollToBottom() {
	    listener = null;
	}
	
	public ScrollBottomScrollView(Context context, AttributeSet attrs) {
	    super(context, attrs);
	}
	
	@Override
	protected void onScrollChanged(int l, int t, int oldl, int oldt) {
	    View view = this.getChildAt(0);
	    if (this.getHeight() + this.getScrollY() == view.getHeight()) {
	        calCount++;
	        if (calCount == 1) {
	            if (listener != null) {
	                listener.scrollToBottom();
	            }
	        }
	    } else {
	        calCount = 0;
	    }
	}
}
scrollView.onScrollViewScrollToBottom(new ScrollBottomScrollView.OnScrollBottomListener() {
     @Override
     public void scrollToBottom() {
           //请求数据
     }});

综合使用:

使用NestedScrollView+ViewPager+RecyclerView+SmartRefreshLayout打造酷炫下拉视差效果并解决各种滑动冲突

ScrollView 使用小结(滑动顶部/底部,吸顶,底部加载,滑动停止监听)

你可能感兴趣的:(代码块,ScrollView总结,ScrollView嵌套,滑动冲突)