0
点赞
收藏
分享

微信扫一扫

2021年你与字节跳动只差这份笔记,使用指南


2021年你与字节跳动只差这份笔记,使用指南_android

一、开始的开始

**Android框架体系架构(高级UI+FrameWork源码)**这块知识是现今使用者最多的,我们称之Android2013~2016年的技术,但是,即使是这样的技术,Android开发者也往往因为网上Copy代码习惯了而导致对这块经常“使用”的代码 **熟悉而又陌生:**熟悉的是几乎天天在和它们打交道,天天在复制这些代码;陌生的是虽然天天和这些代码打交道,但是并没有深入研究过这些代码的原理,代码深处的内涵。

所以我们需要从新的角度去分析这些知识点,深入研究他们,要学习源码,模仿源码,然后再hook源码,这样才能说自己懂这块的知识。这些都是做Android开发,更是做高级工程师的基础。

面试官:说说view中的事件分发?

android中事件分发机制是android中常见的问题,一般大家都知道view的分发事件是从view的​​Viewgroup(Parent)#dispatchTouchEvent​​​到​​Viewgroup(Parent)#onInterceptTouchEvent​​​再到​​View#dispatchTouchEvent​​​,然后到view的​​onTouchEvent​​​,最后又回到了​​Viewgroup(Parent)#onTouchEvent​​。如果大家记不住方法名,可以直接说先是parent的分发到拦截再到view的分发,再到view的消费,最后到parent的消费

2021年你与字节跳动只差这份笔记,使用指南_父类_02

viewgroup分发

这样回答肯定是很浅显的,因为没有说出是否拦截、是否分发、是否消费的各种条件,没有涉及到各种action的分发情况,上面说的默认分发只是针对action_down的,因为​​view/viewgroup​​各种super调用都是不进行分发、拦截、消费的,所以在没找到处理touch事件的view时候,是一直往上层view传递的,一直传到activity里面,下面我们再来整理一下:


如果viewgroup不进行分发,那么​​action_down​​​、​​action_move​​​和​​action_up​​​只会执行到viewgroup的​​dispatchTouchEvent​​​,不分发的条件是​​dispatchTouchEvent​​​直接返回true或false,true和false的区别是true会执行​​action_down​​​、​​action_move​​​和​​action_up​​​,而如果直接返回false只会执行到action_down。并且后续的viewgroup的​​onInterceptTouchEvent​​后续方法都不会被执行到。


关于为什么view/Viewgroup的​​dispatchTouchEvent​​​返回true的时候三个action都能执行到,而返回false的话,只能执行到action_down,这个需要到view/Viewgroup的父类中​​dispatchTouchEvent​​​找答案,该方法中会在action_down的时候调用​​dispatchTransformedTouchEvent​​​方法,而该方法是通过子view的dispatchTouchEvent方法的返回值来决定父类的​​dispatchTransformedTouchEvent​​​方法的返回值,而​​dispatchTransformedTouchEvent​​​的返回值会决定​​mFirstTouchTarget​​​是否为空,所以在action_down的过程中实际中通过子view的​​dispatchTouchEvent​​​方法返回值来确定​​mFirstTouchTarget​​​是否为空。这里贴出viewgroup中​​dispatchTransformedTouchEvent​​方法的删减代码:

private boolean dispatchTransformedTouchEvent(MotionEvent event, boolean cancel,
View child, int desiredPointerIdBits) {
------------------
//省略了cancel部分的代码
------------------------
//如果child为空,直接调用自己的dispatchTouchEvent方法,此时自己就相当于一个view,touch事件走自己的
if (child == null) {
handled = super.dispatchTouchEvent(transformedEvent);
} else {
final float offsetX = mScrollX - child.mLeft;
final float offsetY = mScrollY - child.mTop;
transformedEvent.offsetLocation(offsetX, offsetY);
if (! child.hasIdentityMatrix()) {
transformedEvent.transform(child.getInverseMatrix());
}
//返回值直接通过孩子来获取返回值
handled = child.dispatchTouchEvent(transformedEvent);
}
transformedEvent.recycle();
return handled;
}

所以如果view/viewgroup的​​dispatchTouchEvent​​​方法返回false,表示在action_down的时候,父类的​​dispatchTransformedTouchEvent​​​方法返回false;如果返回true会调用​​addTouchTarget​​​方法,给​​mFirstTouchTarget​​设置值:

private TouchTarget addTouchTarget(@NonNull View child, int pointerIdBits) {
final TouchTarget target = TouchTarget.obtain(child, pointerIdBits);
target.next = mFirstTouchTarget;
mFirstTouchTarget = target;
return target;
}

紧接着在在后面又会调用了:

2021年你与字节跳动只差这份笔记,使用指南_android_03

这句只有在view/viewgroup的​​dispatchTouchEvent​​​返回false的时候,才会走这里,所以后面的​​action_move​​​和​​action_up​​​都会走这里,而此时传入的child=null,从上面代码可以看到,直接调用了父类的​​dispatchTouchEvent​​​方法。所以从这里不难看出在view/viewgroup的​​dispatchTouchEvent​​​返回false的时候直接调用了父类的​​dispatchTouchEvent​​方法,因此只有action_down事件。

面试官:如果我只想有view的拖拽事件,而不想要view的点击事件,让你重写这个view的拖拽怎么设计

其实这道题考察大家对view的dispatchTouchEvent和view的onTouchEvent事件的处理流程,上面已经分析了想要view能执行到view的touch事件,那么必须要求view的​​dispatchTouchEvent​​​返回true,而​​dispatchTouchEvent​​​返回true要么是​​dispatchTouchEvent​​​直接返回true或者view的​​onTouchEvent​​​返回true。如果从效率上看,直接将​​dispatchTouchEvent​​​返回true就ok,而不需要再去关心​​onTouchEvent​​方法。

viewgroup拦截

关于拦截无非就是拦截或不拦截,而拦截的条件是返回true,不拦截是返回false或返回super.onInterceptTouchEvent,默认的super是返回false的,因此可以用super表示不拦截

viewgroup拦截实际是通过在​​dispatchTouchEvent​​​方法中,设置intercepted变量,如果在拦截方法里面返回true,那么intercepted为true,如果为true则在action_down的时候mFirstTouchTarget=null,那么此时是直接调用​​dispatchTransformedTouchEvent​​​传入的child=null,因此将事件交给了​​super.dispatchTouchEvent​​,此时把它当成一个view来处理了。

面试官:有个viewgroup,里面有个view,如果view在dispatchTouchView中不分发事件,并且只在action_move中拦截touch事件向下分发,说说viewgroup到view的各个action是如何分发的?

最后

我这里整理了一份完整的学习思维以及Android开发知识大全PDF,有需要的同学可以自行领取。

2021年你与字节跳动只差这份笔记,使用指南_android_04



举报

相关推荐

0 条评论