这可能是2024大小厂问的最经典的Android面试题了——事件分发机制

本文概述了Android中事件分发的基本原理,涉及Activity、ViewGroup和View之间的事件传递机制,以及View的测量、布局和绘制流程。同时提到了面试中常见的技术要求,如底层源码、NDK、性能优化和跨平台技术如Flutter。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

看了很多博客也看了很多代码,大部分都是长篇大论,不利于阅读固总结如下:

主线传递只有三步:Activity->ViewGroup->View

Activity和View只有两个方法控制事件传递:dispatchTouchEvent(),onTouchEvent ();

ViewGroup有三个方法控制传递:dispatchTouchEvent(),onInterceptTouchEvent(),onTouchEvent ();

接下来用一张图给大家叙述下具体是怎么一步一步分发的。

总结:

1.对于 dispatchTouchEvent,onTouchEvent,return true是终结事件传递。return false 是回溯到父View的onTouchEvent方法。

2.ViewGroup 想把自己分发给自己的onTouchEvent,需要拦截器onInterceptTouchEvent方法return true 把事件拦截下来。

3.ViewGroup 的拦截器onInterceptTouchEvent 默认是不拦截的,所以return super.onInterceptTouchEvent()=return false;

4.View 没有拦截器,为了让View可以把事件分发给自己的onTouchEvent,View的dispatchTouchEvent默认实现(super)就是把事件分发给自己的onTouchEvent。

ViewGroup和View 的dispatchTouchEvent 是做事件分发,那么这个事件可能分发出去的四个目标。

注:------> 后面代表事件目标需要怎么做。

1、 自己消费,终结传递。------->return true ;

2、 给自己的onTouchEvent处理-------> 调用super.dispatchTouchEvent()系统默认会去调用 onInterceptTouchEvent,在onInterceptTouchEvent return true就会去把事件分给自己的onTouchEvent处理。

3、 传给子View------>调用super.dispatchTouchEvent()默认实现会去调用 onInterceptTouchEvent 在onInterceptTouchEvent return false,就会把事件传给子类。

4、 不传给子View,事件终止往下传递,事件开始回溯,从父View的onTouchEvent开始事件从下到上回归执行每个控件的onTouchEvent------->return false

注: 由于View没有子View所以不需要onInterceptTouchEvent 来控件是否把事件传递给子View还是拦截,所以View的事件分发调用super.dispatchTouchEvent()的时候默认把事件传给自己的onTouchEvent处理(相当于拦截),对比ViewGroup的dispatchTouchEvent 事件分发,View的事件分发只有dispatchTouchEvent()和onTouchEvent()不需要onInterceptTouchEvent()参与。

到此事件分发总结完毕。

面试官2:View的渲染过程,或者叫View的绘制流程

这道题也是比较老的一道题了,但是无论BAT还是小创业公司中出现的频率相当高。

接下来就总结性的叙述一遍View绘制流程,避免长篇大论,接下来的描述一切从简。

希望各位读者耐心看完,相信你会有很大的收获!

View绘图流程是在ViewRoot.java类的performTraversals()函数中展开的。

绘制部分一共需要三步:

measure() -> layout() -> draw();

1. 判读是否重新计算视图大小(measure)

原理

从顶层父View像子View递归调用view.measure(),measure方法中回调onMeasure()

MeasureSpec是View的测量内部类,测量规格为int型,值由高2位规格模式specMode和低30位的具体尺寸specSize组成。

specMode有三种值

MeasureSpec.UPSPECIFIED : 父容器对于子容器没有任何限制,子容器想要多大就多大。

MeasureSpec.EXACTLY: 父容器已经为子容器设置了尺寸,子容器应当服从这些边界,不论子容器想要多大的空间。

MeasureSpec.AT_MOST:子容器可以是声明大小内的任意大小

  • View的measure方法是final,不可以重载,只能重载inMeasure完成自己的测量逻辑

  • 顶层的DecorView的MeasureSpec是由ViewRootImpl中的getRootMeasureSpec方法确定(LayoutParams宽高参数均为MATCH_PARENT,specMode是EXACTLY,specSize为物理屏幕大小)。

  • ViewGroup类提供了measureChild,measureChild和measureChildWithMargins方法,简化了父子View的尺寸计算。

  • 只要是ViewGroup的子类就必须要求LayoutParams继承子MarginLayoutParams,否则无法使用layout_margin参数。

  • View的布局大小由父View和子View共同决定。

  • 使用View的getMeasuredWidth()和getMeasuredHeight()方法来获取View测量的宽高,必须保证这两个方法在onMeasure流程之后被调用才能返回有效值。

2. 是否重新分配视图的位置(layout)

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

深知大多数初中级安卓工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

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

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Android)
img

Android开发除了flutter还有什么是必须掌握的吗?

相信大多数从事Android开发的朋友们越来越发现,找工作越来越难了,面试的要求越来越高了

除了基础扎实的java知识,数据结构算法,设计模式还要求会底层源码,NDK技术,性能调优,还有会些小程序和跨平台,比如说flutter,以思维脑图的方式展示在下图;

点击文档前往获取面试资料与视频教程;【阿里P7级别Android架构师技术脑图+全套视频】

求会底层源码,NDK技术,性能调优,还有会些小程序和跨平台,比如说flutter,以思维脑图的方式展示在下图;

点击文档前往获取面试资料与视频教程;【阿里P7级别Android架构师技术脑图+全套视频】

[外链图片转存中…(img-4V51uMoj-1711104455145)]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值