NestScrollView原理解析,年末阿里百度等大厂技术面试题汇总

}

@Override

public boolean dispatchNestedFling(float velocityX, float velocityY, boolean consumed) {

return mScrollingChildHelper.dispatchNestedFling(velocityX, velocityY, consumed);

}

@Override

public boolean dispatchNestedPreFling(float velocityX, float velocityY) {

return mScrollingChildHelper.dispatchNestedPreFling(velocityX, velocityY);

}

从代码中可以看到,RecyclerView充当了一个代理的角色,它的很多逻辑其实是交给 NestedScrollingChildHelper 去帮助其完成的,下面我们一起来看一下 NestedScrollingChildHelper 里的方法

/**

  • Start a new nested scroll for this view.

  • This is a delegate method. Call it from your {@link android.view.View View} subclass

  • method/{@link NestedScrollingChild} interface method with the same signature to implement

  • the standard policy.

  • @param axes Supported nested scroll axes.

  •         See {@link NestedScrollingChild#startNestedScroll(int)}.
    
  • @return true if a cooperating parent view was found and nested scrolling started successfully

*/

public boolean startNestedScroll(int axes) {

if (hasNestedScrollingParent()) {

// Already in progress

return true;

}

if (isNestedScrollingEnabled()) {

ViewParent p = mView.getParent();

View child = mView;

while (p != null) {

if (ViewParentCompat.onStartNestedScroll(p, child, mView, axes)) {

mNestedScrollingParent = p;

ViewParentCompat.onNestedScrollAccepted(p, child, mView, axes);

return true;

}

if (p instanceof View) {

child = (View) p;

}

p = p.getParent();

}

}

return false;

}

  1. 第一步,判断 P 是否为空,不为空, 从 P (初始值是RecyclerView 的直接父 View) 开始找起,判断其是否支持嵌套滑动,若支持,返回true;

  2. 第二步:若 P 不支持嵌套滑动,再将 p 指向 p.getParent(),循环第一步;

  3. 第三步:若循环了所有的 P ,都找不到支持嵌套滑动的 View,返回 false。

/**

  • Dispatch one step of a nested scrolling operation to the current nested scrolling parent.

  • This is a delegate method. Call it from your {@link android.view.View View} subclass

  • method/{@link NestedScrollingChild} interface method with the same signature to implement

  • the standard policy.

  • @return true if the parent consumed any of the nested scroll

*/

public boolean dispatchNestedScroll(int dxConsumed, int dyConsumed,

int dxUnconsumed, int dyUnconsumed, int[] offsetInWindow) {

if (isNestedScrollingEnabled() && mNestedScrollingParent != null) {

if (dxConsumed != 0 || dyConsumed != 0 || dxUnconsumed != 0 || dyUnconsumed != 0) {

int startX = 0;

int startY = 0;

if (offsetInWindow != null) {

mView.getLocationInWindow(offsetInWindow);

startX = offsetInWindow[0];

startY = offsetInWindow[1];

}

ViewParentCompat.onNestedScroll(mNestedScrollingParent, mView, dxConsumed,

dyConsumed, dxUnconsumed, dyUnconsumed);

if (offsetInWindow != null) {

mView.getLocationInWindow(offsetInWindow);

offsetInWindow[0] -= startX;

offsetInWindow[1] -= startY;

}

return true;

} else if (offsetInWindow != null) {

// No motion, no dispatch. Keep offsetInWindow up to date.

offsetInWindow[0] = 0;

offsetInWindow[1] = 0;

}

}

return false;

}

当childView已发生滑动时,首先获取childView在屏幕上的位置并记录X, Y坐标,因为上一步在startNestedScroll 方法中已完成对 mNestedScrollingParent的初始化,在这里调用 ViewParentCompat.onNestedScroll(mNestedScrollingParent, mView, dxConsumed,

dyConsumed, dxUnconsumed,dyUnconsumed),最后重新获取滑动后的childView在屏幕上的位置,并将childView左上角的X,Y轴坐标重新赋值为当前位置与初始位置之差;当childView未发生滑动时,直接将childView左上角的X,Y轴坐标赋值为0。

看完了上面的两个主要方法,我们可以得出这样的一个结论:当我们调用 Scrolling Child 的 onStartNested 方法的时候,会通过 ChildHelper 去寻找是否有相应的 Scrolling Parent,如果有的话,会 回调相应的方法。同理 dispatchNestedPreScroll,dispatchNestedScroll,dispatchNestedPreFling 同样如此。

public boolean onTouchEvent(MotionEvent e) {

// 如果 Item 处理了 Touch 事件,直接返回 true ,在在处理

if (dispatchOnItemTouch(e)) {

cancelTouch();

return true;

}

if (mLayout == null) {

return false;

}

switch (action) {

case MotionEvent.ACTION_DOWN: {

mScrollPointerId = e.getPointerId(0);

mInitialTouchX = mLastTouchX = (int) (e.getX() + 0.5f);

mInitialTouchY = mLastTouchY = (int) (e.getY() + 0.5f);

int nestedScrollAxis = ViewCompat.SCROLL_AXIS_NONE;

if (canScrollHorizontally) {

nestedScrollAxis |= ViewCompat.SCROLL_AXIS_HORIZONTAL;

}

if (canScrollVertically) {

nestedScrollAxis |= ViewCompat.SCROLL_AXIS_VERTICAL;

}

// 在 Action_Down 的时候 调用 startNestedScroll

startNestedScroll(nestedScrollAxis);

} break;

case MotionEvent.ACTION_MOVE: {

// 在 Action_move 的时候,回调 dispatchNestedPreScroll 方法

if (dispatchNestedPreScroll(dx, dy, mScrollConsumed, mScrollOffset)) {

// 减去 Scrolling Parent 的消费的值

dx -= mScrollConsumed[0];

dy -= mScrollConsumed[1];

vtev.offsetLocation(mScrollOffset[0], mScrollOffset[1]);

// Updated the nested offsets

mNestedOffsets[0] += mScrollOffset[0];

mNestedOffsets[1] += mScrollOffset[1];

}

if (mScrollState == SCROLL_STATE_DRAGGING) {

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以添加V获取:vip204888 (备注Android)
img

面试复习笔记:

这份资料我从春招开始,就会将各博客、论坛。网站上等优质的Android开发中高级面试题收集起来,然后全网寻找最优的解答方案。每一道面试题都是百分百的大厂面经真题+最优解答。包知识脉络 + 诸多细节。
节省大家在网上搜索资料的时间来学习,也可以分享给身边好友一起学习。

《960页Android开发笔记》

《1307页Android开发面试宝典》

包含了腾讯、百度、小米、阿里、乐视、美团、58、猎豹、360、新浪、搜狐等一线互联网公司面试被问到的题目。熟悉本文中列出的知识点会大大增加通过前两轮技术面试的几率。

《507页Android开发相关源码解析》

只要是程序员,不管是Java还是Android,如果不去阅读源码,只看API文档,那就只是停留于皮毛,这对我们知识体系的建立和完备以及实战技术的提升都是不利的。

真正最能锻炼能力的便是直接去阅读源码,不仅限于阅读各大系统源码,还包括各种优秀的开源库。

,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新**

如果你觉得这些内容对你有帮助,可以添加V获取:vip204888 (备注Android)
[外链图片转存中…(img-0pOk4L66-1711781552075)]

面试复习笔记:

这份资料我从春招开始,就会将各博客、论坛。网站上等优质的Android开发中高级面试题收集起来,然后全网寻找最优的解答方案。每一道面试题都是百分百的大厂面经真题+最优解答。包知识脉络 + 诸多细节。
节省大家在网上搜索资料的时间来学习,也可以分享给身边好友一起学习。

《960页Android开发笔记》

[外链图片转存中…(img-cyvcQ2LP-1711781552075)]

《1307页Android开发面试宝典》

包含了腾讯、百度、小米、阿里、乐视、美团、58、猎豹、360、新浪、搜狐等一线互联网公司面试被问到的题目。熟悉本文中列出的知识点会大大增加通过前两轮技术面试的几率。

[外链图片转存中…(img-duHkNaCn-1711781552075)]

《507页Android开发相关源码解析》

只要是程序员,不管是Java还是Android,如果不去阅读源码,只看API文档,那就只是停留于皮毛,这对我们知识体系的建立和完备以及实战技术的提升都是不利的。

真正最能锻炼能力的便是直接去阅读源码,不仅限于阅读各大系统源码,还包括各种优秀的开源库。

本文已被CODING开源项目:《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》收录

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值