Android View大厂面试题(一)

作者: 在岁月中远行 | 来源:发表于2022-08-14 01:49 被阅读0次

题目如下:View事件传递;事件是从哪里到达Activity的?ViewRootImpl的作用?有A、B两个Button,各自设置了OnClickListener,在A上按下,移动到B上抬起,会触发OnClickListener么?为何?UP事件谁接收到了?OnClickListener触发的条件是哪些?

1.1 View事件传递;事件是从哪里到达Activity的?

这个以后专门写一篇文章单独分析事件如何从屏幕点击最终到达Activity的。

1.2 基本三大作用:

作为WindowManager和DecorView的纽带,桥梁。

完成View的绘制过程,包括measure,layout,draw过程。

向DecorView分发收到的用户发起的Event事件,比如按键、触屏事件等。

1.3  我们先用代码验证,然后再结合源码来分析

按照在A按钮按下,然后一直移动 直到B按钮位置才抬起来 结果是:

刚按下时候触发A按钮的 ACTION_DOWN,然后在A范围内移动,触发ACTION_MOVE,当不在A范围内移动时,没有事件触发,然后又移动到A范围内,依然ACTION_MOVE。最后再移动到B按钮上抬起,触发A按钮的ACTION_UP。过程中没有触发B按钮任何事件。

不会触发OnClickListener

1.4 UP事件被A按钮收到了。

1.5 源码来分析:

首先看不会触发OnClickListener原因。

而Onclick事件是在UP事件中触发

可以看到逻辑也比较简单:当触发ACTION_UP事件时,也就是手指抬起时,当View处于Pressed状态。就会触发performClickInternal()。这里面也会调用performClick。也就是回调onClick。

所以结论:当A按钮移出View后再B后抬起是不会触发onClick事件的。

UP事件没有被B按钮处理是B都没有处理ACTION_DOWN事件(这是一个事件序列的开端)。显然是不会触发UP事件的。

1.6 OnClickListener触发的条件是哪些?

先给出结论 

设置了setOnClicklistener

View没有重写OnTouchEvent(默认情况下 这个方法返回值是clickable,也就是说View如果是可点击的,那么就会消耗事件)

手指没有移动出View的范围

有抬起动作。

现在主要分析下如果View重写OnTouchEvent的情况。为什么就不会触发了OnClick事件了。

当我重写onTouchEvent 无论之间返回false或者ture时,都不会触发了onClick事件

此时的日志始终没有打印。其实想想也是我们的onClick回调是在View#onTouchEvent的ACTION_UP那一段代码触发的。我们点击按钮时候都没触发View的onTouchEvent方法怎么会进行onClick回调呢。

当自定义View时候重写了onTouchEvent方法后,还想要响应onClick回调时,可以在ACTION_UP里面手动调用

return true;

当返回return super.onTouchEvent(event);

现象:onClick 会触发两次

当返回return false; 不会触发,即使调用了performClick(); 因为return false代表View不处理此事件了。

相关文章

网友评论

    本文标题:Android View大厂面试题(一)

    本文链接:https://www.haomeiwen.com/subject/wklzwrtx.html