NestedScrollView嵌套滑动源码解读

1、前言

滑动对于android来说,是一个必不可少;它不复杂,大家都知道在onTouchEvent中,让它滑动就完事了,说它复杂,其嵌套处理复杂;在本系列文章,最终是为了熟悉嵌套滑动机制;对于滑动,分为下面几篇文章来完成解读:

在本章内,本章从两个嵌套的两个视角来分析

  1. 子滑动视图视角:涉及NestedScrollingChild3接口以及NestedScrollingChildHelper辅助类
  2. 父滑动容器视角:涉及NestedScrollingParent3接口以及NestedScrollingParentHelper辅助类

这篇内容分三个小章节

  1. NestedScrollingChildHelper类
  2. NestedScrollingParentHelper类
  3. 实现处理以及调用时机

在这里类的解读是必须的,不然只能死记其调用时机,这里是不建议的;下面会贴一部分源码,在源码中会对代码的一些关键进行注释说明

2、NestedScrollingChildHelper类

嵌套子视图角色;主要功能

  • 事件是否需要通知
  • 事件通知

类中如下变量:

    private ViewParent mNestedScrollingParentTouch; // touch事件接力的父容器
    private ViewParent mNestedScrollingParentNonTouch; // 非touch事件接力的父容器
    private final View mView; // 当前容器,也是作为嵌套滑动时孩子角色的容器
    private boolean mIsNestedScrollingEnabled; // 当前容器是否支持嵌套滑动
    private int[] mTempNestedScrollConsumed; // 二维数组,保存x、y消耗的事件长度;减少对象生成的
复制代码

2.1 实例获取

    public NestedScrollingChildHelper(@NonNull View view) {
        mView = view;
    }
复制代码

2.2 嵌套滑动支持

是对嵌套子视图的角色来说的

    public void setNestedScrollingEnabled(boolean enabled) {
        if (mIsNestedScrollingEnabled) {
            ViewCompat.stopNestedScroll(mView); // 兼容模式调用
        }
        mIsNestedScrollingEnabled = enabled;
    }

    public boolean isNestedScrollingEnabled() {
        return mIsNestedScrollingEnabled;
    }
复制代码

2.3 嵌套滑动相关方法

要支持嵌套滑动,那么必须有多个支持嵌套滑动的容器;作为子视图,其需要有通知的一套,因此方法有:

  • 父容器的查找、判断
  • 通知开始、过程以及结束
2.3.1 嵌套父容器的查找

成员变量mNestedScrollingParentTouch、mNestedScrollingParentNonTouch为父容器缓存变量;其直接设置和获取方法如下

  private ViewParent getNestedScrollingParentForType(@NestedScrollType int type) {
        switch (type) {
            case TYPE_TOUCH:
                return mNestedScrollingParentTouch;
            case TYPE_NON_TOUCH:
                return mNestedScrollingParentNonTouch;
        }
        return null;
    }

    private void setNestedScrollingParentForType(@NestedScrollType int type, ViewParent p) {
        switch (type) {
            case TYPE_TOUCH:
                mNestedScrollingParentTouch = p;
                break;
            case TYPE_NON_TOUCH:
                mNestedScrollingParentNonTouch = p;
                break;
        }
    }
复制代码
2.3.2 嵌套父容器的支持判断
    public boolean hasNestedScrollingParent() {
        return hasNestedScrollingParent(TYPE_TOUCH);
    }

    public boolean hasNestedScrollingParent(@NestedScrollType int type) {
        return getNestedScrollingParentForType(type) != null;
    }
复制代码
2.3.3 滑动开始通知
    public boolean startNestedScroll(@ScrollAxis int axes, @NestedScrollType int type) {
        if (hasNestedScrollingParent(type)) {
            return true;
        }
        if (isNestedScrollingEnabled()) { // 孩子视图支持嵌套滑动,只有支持才会继续执行
            ViewParent p = mView.getParent();
            View child = mView;
            while (p != null) { // 查找的不仅仅直接父容器
                // 兼容调用,父容器是否可以作为嵌套父容器角色
                if (ViewParentCompat.onStartNestedScroll
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值