NestedScrollView使用和理解

https://www.jianshu.com/p/fda06c916d6b
一、前言:

NestedScrollView支持嵌套滑动的 ScrollView

因此,我们可以简单的把 NestedScrollView 类比为 ScrollView,其作用就是作为控件父布局,从而具备(嵌套)滑动功能。

NestedScrollViewScrollView 的区别就在于 NestedScrollView 支持 嵌套滑动,无论是作为父控件还是子控件,嵌套滑动都支持,且默认开启。

因此,在一些需要支持嵌套滑动的情景中,比如一个 ScrollView 内部包裹一个 RecyclerView,那么就会产生滑动冲突,这个问题就需要你自己去解决。而如果使用 NestedScrollView 包裹 RecyclerView,嵌套滑动天然支持,你无需做什么就可以实现前面想要实现的功能了。

举个例子:

我们通常为RecyclerView增加一个 Header 和 Footer 的方法是通过定义不同的 viewType来区分的,而如果使用 NestedScrollView,我们完全可以把RecyclerView当成一个单独的控件,然后在其上面增加一个控件作为 Header,在其下面增加一个控件作为 Footer。

具体布局如下所示:

 

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:descendantFocusability="blocksDescendants"
        android:orientation="vertical">

        <!-- This is the Header -->
        <TextView
            android:layout_width="match_parent"
            android:layout_height="200dp"
            android:background="#888888"
            android:gravity="center"
            android:text="Header"
            android:textColor="#0000FF"
            android:textSize="30sp" />

        <android.support.v7.widget.RecyclerView
            android:id="@+id/rc"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />

        <!-- This is the Footer -->
        <TextView
            android:layout_width="match_parent"
            android:layout_height="200dp"
            android:background="#888888"
            android:gravity="center"
            android:text="Footer"
            android:textColor="#FF0000"
            android:textSize="30sp" />

    </LinearLayout>

</android.support.v4.widget.NestedScrollView>

注: NestedScrollViewScrollView 一样,内部只能容纳一个子控件。

效果如下所示:

 

aaaa.gif

ps: 虽然 NestedScrollView 内嵌RecyclerView和其他控件可以实现 Header 和 Footer,但还是不推荐上面这种做法(建议还是直接使用RecyclerView自己添加 Header 和 Footer),因为虽然 NestedScrollView 支持嵌套滑动,但是在实际应用中,嵌套滑动可能会带来其他的一些奇奇怪怪的副作用,Google 也推荐我们能不使用嵌套滑动就尽量不要使用。

如果想知道 NestedScrollView 嵌套其他控件可能带来的问题,可以查看:NestedScrollView、RecycleView、ViewPager 等布局方面的常见问题汇总,及解决

二、 嵌套滑动机制 简析

我们知道,Android 的事件分发机制中,只要有一个控件消费了事件,其他控件就没办法再接收到这个事件了。因此,当有嵌套滑动场景时,我们都需要自己手动解决事件冲突。而在 Android 5.0 Lollipop 之后,Google 官方通过 嵌套滑动机制 解决了传统 Android 事件分发无法共享事件这个问题。

嵌套滑动机制 的基本原理可以认为是事件共享,即当子控件接收到滑动事件,准备要滑动时,会先通知父控件(startNestedScroll);然后在滑动之前,会先询问父控件是否要滑动(dispatchNestedPreScroll);如果父控件响应该事件进行了滑动,那么就会通知子控件它具体消耗了多少滑动距离;然后交由子控件处理剩余的滑动距离;最后子控件滑动结束后,如果滑动距离还有剩余,就会再问一下父控件是否需要在继续滑动剩下的距离(dispatchNestedScroll)...

上面其实就是 嵌套滑动机制 的工作原理,那么如果想让我们自定义的View或者ViewGroup实现嵌套滑动功能,应该怎样做呢?

其实,在 Android 5.0 之后,系统自带的ViewViewGroup都增加了 嵌套滑动机制 相关的方法了(但是默认不会被调用,因此默认不具备嵌套滑动功能),所以如果在 Android 5.0 及之后的平台上,自定义View只要覆写相应的 嵌套滑动机制 相关方法即可;但是为了提供低版本兼容性,Google 官方还提供了两个接口,分别作为 嵌套滑动机制 父控件接口和子控件接口:

前面我们说过 NestedScrollView 无论是作为父控件还是子控件都支持嵌套滑动,就是因为它同时实现了 NestedScrollingParentNestedScrollingChild。文档如下所示:

图片.png

三、注意:

  • NestedScrollView主要用于非列表(除ListView和RecyclerView)间的滑动比较好;
  • NestedScrollView嵌套RecyclerView会导致复用失效,看了很多网友的帖子,一直没有很好的解决方案;
  • 如果RecyclerView数据量很少,可以复用的;
  • 建议给RecyclerView添加头部和尾部的方式,弃用NestedScrollView;

查看详细分析:https://www.jianshu.com/p/f55abc60a879

参考



作者:因为我的心
链接:https://www.jianshu.com/p/fda06c916d6b
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

  • 7
    点赞
  • 38
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值