AppBarLayout.Behavior探究

Appbarlayout.Behavior
1.作用
处理嵌套滚动偏移处理
2.分析思路
从程序的执行起始点开始分析
3.层级结构
Appbarlayout --> HeaderBehavior --> ViewOffsetBehavior --> Coordinatorlayout.Behavior
4.嵌套处理
onStartNestedScroll 决定是否嵌套滚动 条件:垂直滚动 Appbarlayout拥有可以滚动的子View CoordinatorLayout的高度-其他的直接子View的高度 小于等于 Appbarlayout的高度
5.Appbarlayout拥有可以滚动的子View(getTotalScrollRange() != 0)
也就是说所有的滚动范围不能等于0的时候才满足条件,这里会对Appbarlayout的所有的子View进行一次遍历,SCROLL _FLAG_SCROLL = 0x1&x != 0,如果子View的scrollFlag拥有标示.并且标示是奇数才会满足也就是Scroll的标示,计算子View 的全部高度,包含了边距
其次如果标示等于CROLL _FLAG_EXIT _UNTIL_COLLAPSED rang范围高度好需要通过ViewCompat.getMinimumHeight(child)(这个方法在Api16会返回0,参考反射)减去其最小高度,最后如果rang-getTopInset()小于0就取0,
getTopInset()这里是窗口插入view的时候在api21以上才会出发,如果布局开启了fitWindow那么getTopInset = 布局有效区域(这里受到输入法 状态栏 导航栏等影响)的顶部距离,最终得到的才是有效的滚动范围
getTotalScrollRange() 这里在布局进行初始化的时候已经对其孩子的高度进行了计算,这里会有一个优化 if (mTotalScrollRange != INVALID _SCROLL_RANGE) {return mTotalScrollRange; } 避免了多次计算的问题,逻辑优化,也就是说后期是直接拿到初始化布局的高度的,如果想重新计算一下高度可以试着通过改变mTotalScrollRange = INVALID _SCROLL_RANGE;进行修改
6.directTargetChild代表的什么 例子中是NestScrollView target View代表触发的View
CoordinatorLayout的子View或者是包含嵌套滚动的View
7.CoordinatorLayout的高度-其他的直接子View的高度 小于等于 Appbarlayout的高度
也就是说CoordinatorLayout的高度-其他的View的总高度如果小于等于AppbarLayout的话就会之星滚动动作
1686-0=1686 1686-168(168的正好是Appbarlayout的底部高度)= <= 168
8.getDownNestedPreScrollRange 分析Appbarlayout的最小可滑动范围
在第一次触发了以后就不会在此触发了,也是为了避免重复计算减少绘制时间,FLAG _QUICK_RETURN = SCROLL _FLAG_SCROLL | SCROLL _FLAG_ENTER_ALWAYS;这里需要两个标示才能满足
SCROLL _FLAG_ENTER _ALWAYS_COLLAPSED这个标示表示下拉的范围事Appbarlayout的子View的最小高度的总和 SCROLL _FLAG_EXIT _UNTIL_COLLAPSED 表示下滑范围是子View的高度-最小高度的总和
其他的标示 其子View的高度作为滑动的范围如果开启了fitWindow那么还需要减去这个高度,
9.onNestedPreScroll 嵌套滚动发生之前调用
内部执行条件:dy 向上为正 向下为负 如果滑动距离不等于0并且mSkipNestedPreScroll=false,如果dy小于0 说明是向下的 否则是向上的 getUpNestedPreScrollRange = getTotalScrollRange
10.interpolateOffset 差值器处理以后的偏移值
这里只会在差值器不为空的时候才会有效果,首先对偏移值取绝对值,然后遍历Appbarlayout中的所有的子View,拿到子View的差值器,如果说当前偏移的位置在某个view top等于 和 bottom等于 之间的位置,这里分为四种情况 SCROLL _FLAG_SCROLL SCROLL _FLAG_EXIT _UNTIL_COLLAPSED getFitsSystemWindows 每个View的可滚动范围必须大于0 ,最红会通过计算已滚动距离相对于view的比例得出差值器以后对应的值
11.scroll 执行滚动效果可以说是用来设置用来更新的参数
setHeaderTopBottomOffset 设置头部位置偏移,返回当前已经偏移的距离 getTopBottomOffsetForScrollingSibling = getTopAndBottomOffset 获取当前滚动的距离向上为负,
如果最小偏移不等于0 并且 当前的便宜位置在可滚动区间之间(MathUtils.constrain newOffest如果在区间之内那么就返回当前的offest如果小于那么就返回最小值,如果大于最大值那么就返回最大值)
这里如果设置了差值器newoffest就会发生变化,然后偏移的距离通过setTopAndBottomOffset,如果和上次的偏移相同那么就返回false否则就是true。 mOffsetDelta记录了原值和差值器值的差值,如果偏移并没有改变,dispatchDependentViewsChanged遍历依赖view的集合,调用behavior.onDependentViewChanged用来更新视图,然后通过dispatchOffsetUpdates分发所有的偏移事件,getAppBarChildOnOffset获取当前偏移所处的View,updateAppBarLayoutDrawableState更新drawable的状态。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值