问题分析

嵌套滑动一直是Android中比较棘手的问题, 根本原因是Android的事件分发机制导致的.不了解事件分发机制的同学可以先看看一点见解: Android事件分发机制, 导致嵌套滑动难处理的关键原因在于当子控件消费了事件, 那么父控件就不会再有机会处理这个事件了, 所以一旦内部的滑动控件消费了滑动操作, 外部的滑动控件就再也没机会响应这个滑动操作了

嵌套滑动

不过这个问题终于在LOLLIPOP(SDK21)之后终于有了官方的解决方法, 就是嵌套滑动机制. 在分析具体的代码逻辑之前, 下面先简单介绍下嵌套滑动的一些基本知识.
嵌套滑动机制可以理解为一个约定, 原生的支持嵌套滑动的控件都是依据这个约定来实现嵌套滑动的, 例如CoordinatorLayout, 所以如果你自定义的控件也遵守这个约定, 那么就可以跟原生的控件进行嵌套滑动了

基本原理

嵌套滑动的基本原理是在子控件滑动一段距离的请求时,先询问父控件是否要滑动,如果滑动了父控件就通知子控件它消耗了一部分滑动距离,子控件就只处理剩下的滑动距离,然后子控件滑动完毕后把剩余的滑动距离传给父控件。

版本区别

SDK21之后

嵌套滑动的相关逻辑作为普通方法写进了ViewViewGroup类,例如dispatchNestedScroll()

SDK21之前

官方在android.support.v4兼容包中提供了两个接口NestedScrollingChildNestedScrollingParent,还有两个辅助类NestedScrollingChildHelperNestedScrollingParentHelper来帮助控件实现嵌套滑动.
这个兼容的原理很简单
两个接口NestedScrollingChildNestedScrollingParent分别定义上面提到的View和ViewParent新增的普通方法
在代码中是通过ViewCompatViewParentCompat类来判断调用的方法是控件自有的方法, 还是接口的方法
如果版本是SDK21之前, 那么就会判断控件是否实现了接口, 然后调用接口的方法, 如果是SDK21之后, 那么就可以直接调用对应的方法.

接下来通过分析相对简单的支持嵌套滑动的容器NestedScrollView来了解下怎样主动调起嵌套滑动的方法, 以及嵌套滑动的具体逻辑.

相关方法

NestedScrollingChild

startNestedScroll : 起始方法, 主要作用是找到接收滑动距离信息的外控件.
dispatchNestedPreScroll : 在内控件处理滑动前把滑动信息分发给外控件.
dispatchNestedScroll : 在内控件处理完滑动后把剩下的滑动距离信息分发给外控件.
stopNestedScroll : 结束方法, 主要作用就是清空嵌套滑动的相关状态
setNestedScrollingEnabledisNestedScrollingEnabled : 一对get&set方法, 用来判断控件是否支持嵌套滑动.
dispatchNestedPreFlingdispatchNestedFling : 跟Scroll的对应方法作用类似, 不过分发的不是滑动信息而是Fling信息.(这个Fling好难翻译.. =。=)本文主要关注滑动的处理, 所以后续不分析这两个方法.

NestedScrollingParent

因为内控件是发起者, 所以外控件的大部分方法都是被内控件的对应方法回调的.
onStartNestedScroll : 对应startNestedScroll, 内控件通过调用外控件的这个方法来确定外控件是否接收滑动信息.
onNestedScrollAccepted : 当外控件确定接收滑动信息后该方法被回调, 可以让外控件针对嵌套滑动做一些前期工作.
onNestedPreScroll : 关键方法, 接收内控件处理滑动前的滑动距离信息, 在这里外控件可以优先响应滑动操作, 消耗部分或者全部滑动距离.
onNestedScroll : 关键方法, 接收内控件处理完滑动后的滑动距离信息, 在这里外控件可以选择是否处理剩余的滑动距离.
onStopNestedScroll : 对应stopNestedScroll, 用来做一些收尾工作.
getNestedScrollAxes : 返回嵌套滑动的方向, 区分横向滑动和竖向滑动, 作用不大
onNestedPreFling和onNestedFling : 同上略

从NestedScrollView看嵌套机制

更多相关文章

  1. android中使用httpclient方法获得网页内容并对json对象解析
  2. Android Studio3.0开发JNI流程------在Android原程序添加自己类
  3. 利用Android的Matrix类实现J2ME的drawRegion的镜像方法
  4. 一个非常好用的自定义圆形控件
  5. Systrace 分析性能工具使用方法详解
  6. 简单的Android ROM制作方法:创建刷机包 备份ROM
  7. ScrollView中若嵌套有滑动的控件(如:WebView,ListView或GridView)
  8. Android原生Switch控件滑块thumb卡住问题的解决方法

随机推荐

  1. Android实现全屏的方法
  2. UI 开源代码 FileBrowserView
  3. android根据ListView内部Item最大长度来
  4. Android设定屏幕只竖屏或只横屏的两种方
  5. 如何关联androidSDK源代码
  6. Android 全局Activity动画设置
  7. Android开发9——Activity的启动模式
  8. 浅谈Android Surface机制
  9. Android的闹钟管理类
  10. 9.RatingBar