事件传递(android)常见面试题
一.事件分发传递流程
Android 事件分发传递流程主要分为三个阶段:事件分发阶段、事件捕获阶段和事件处理阶段。下面我将进一步解释这三个阶段的具体内容:
- 事件分发阶段
事件分发阶段是从 Activity 的 dispatchTouchEvent() 方法开始,在这一阶段中,系统会先将事件传递给 ViewRootImpl,再由 ViewRootImpl 分发到 Activity 的 decorView,最后通过 View 的 onTouchEvent() 方法交给子 view。
具体流程如下:
-
Activity 从 ViewRootImpl 中获取 MotionEvent 事件。
-
ViewRootImpl 调用 ViewGroup 中的 dispatchTouchEvent() 方法,将事件分发给对应的子 View 进行处理。
-
子 View 依次递归处理事件,如果有子 View 拦截了事件,那么事件就不会再继续传递下去。
-
如果根据 onTouchEvent() 返回结果判断当前 View 处理了事件,那么事件就不会向子 View 再次传递。
-
如果事件都没有被拦截,那么这个事件将传递到 Activity 中的 onTouchEvent() 方法中。
-
事件捕获阶段
事件捕获阶段是指事件从根 View 开始,依次由父 View 捕获,直到当前 View,同时将事件自下向上传递给其祖先 View 的一种机制。主要是为了方便更改事件的属性,例如事件的坐标等。
具体流程如下:
-
系统会先将事件传递给该事件的目标 View,并将事件从根节点向下传递。
-
在向下子 View 传递事件时,父级 View 可以拦截事件并记录事件的坐标。
-
当事件传递到目标 View 的时候,事件的坐标信息会被用来进行对 View 执行操作的计算和判定。
-
如果当前 View 拦截了事件,那么此后的再次触摸事件都会被该 View 标记为 “拦截状态”,直到事件处理完毕,被放手传递给上级 View。
-
事件处理阶段
事件处理阶段是指最终处理 MotionEvent 的对象(除系统级别的)或者被设置成 Action.Cancel 的最后一个 View。在处理阶段中,会根据 View 的事件类型判断该事件是否可以被处理,如果可以则会继续进行处理,否则会将事件传递给父 View 或者其他 View 进行处理,直至事件被处理或者被放弃。
具体流程如下:
-
当一个 View 接收到一个 MotionEvent 事件时,它会首先检查自己的 onTouchEvent() 方法是否可以处理该事件。
-
如果当前 View 无法处理该事件,那么事件会被传递给上一级父 View 进行处理。
-
如果事件一直没有被处理,那么最终会将事件交给系统完成处理。
总的来说,Android 事件分发传递流程的机制是基于 View 树的节点结构,并且支持通过拦截事件、处理事件和返回事件等手段实现对事件的监测、干涉和响应。对于 Android 开发人员而言,深刻理解这个事件流程,有助于更完善地开发自己的 Android 应用程序。
二. Android常见的事件类型以及监听方式
Android 事件驱动机制是指通过一系列的事件监听器和回调函数来实现对用户交互操作的监听和相应的机制。Android 系统支持多种类型的事件监听器,包括触摸事件监听器、键盘事件监听器、手势事件监听器等,并且通过回调函数来实时监听用户的操作,从而实现对应用程序的控制和交互。下面我将分别介绍一下 Android 事件驱动机制中的各种监听器和回调函数:
- 触摸事件监听器
触摸事件监听器是 Android 事件驱动机制中的核心部分,主要用于对触摸事件的监听和处理。在 Android 中,触摸事件可以通过 MotionEvent 类来描述,主要包括三种基本的事件类型:ACTION_DOWN、ACTION_MOVE 和 ACTION_UP。可以通过实现 OnTouchListener 接口来监听触摸事件,并重写 onTouch() 方法来处理事件。例如:
view.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
// 处理按下事件
break;
case MotionEvent.ACTION_MOVE:
// 处理移动事件
break;
case MotionEvent.ACTION_UP:
// 处理抬起事件
break;
}
return false;
}
});
- 键盘事件监听器
键盘事件监听器与触摸事件监听器类似,主要用于对键盘事件的监听和处理。在 Android 中,键盘事件可以通过 KeyEvent 类来描述,主要包括 ACTION_DOWN 和 ACTION_UP 两种基本的事件类型。可以通过实现 OnKeyListener 接口来监听键盘事件,并重写 onKey() 方法来处理事件。例如:
view.setOnKeyListener(new View.OnKeyListener() {
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (event.getAction() == KeyEvent.ACTION_DOWN) {
switch (keyCode) {
case KeyEvent.KEYCODE_VOLUME_UP:
// 处理音量键加事件
break;
case KeyEvent.KEYCODE_VOLUME_DOWN:
// 处理音量键减事件
break;
}
}
return false;
}
});
- 手势事件监听器
手势事件监听器主要用于对手势事件的监听和处理。在 Android 中,手势事件需要使用 GestureDetector 类来进行监听,并实现 OnGestureListener 和 OnDoubleTapListener 接口来处理手势事件。例如:
// 在 Activity 中实例化 GestureDetector,并将它绑定到 View 上
GestureDetector gestureDetector = new GestureDetector(this, new GestureDetector.SimpleOnGestureListener() {
@Override
public boolean onSingleTapConfirmed(MotionEvent e) {
// 处理单击事件
return super.onSingleTapConfirmed(e);
}
@Override
public boolean onDoubleTap(MotionEvent e) {
// 处理双击事件
return super.onDoubleTap(e);
}
});
// 绑定 OnTouchListener 和 OnGestureListener
view.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
return gestureDetector.onTouchEvent(event);
}
});
除了上述的三种事件监听器,Android 还提供了多种其他类型的事件监听器,例如文本变化监听器、列表滚动监听器、视图绘制监听器等,这些监听器通过实现相应的接口和重写对应的回调函数来实现对应用程序的控制和响应。
转载自:https://juejin.cn/post/7233720373236678716