Android面试题库
Framework源码
View事件分发机制

View事件分发机制

本章节将详细介绍Android中View的事件分发机制,包括事件传递流程、源码分析和常见面试题。

核心问题

  1. 简述Android的事件分发机制
  2. Activity、ViewGroup、View三者的事件分发顺序是怎样的?
  3. 如何解决滑动冲突?

事件分发流程

基本流程

事件分发的顺序是:Activity -> Window -> DecorView -> ViewGroup -> View

// ViewGroup的事件分发方法
public boolean dispatchTouchEvent(MotionEvent ev) {
    boolean handled = false;
    if (onInterceptTouchEvent(ev)) {
        handled = onTouchEvent(ev);
    } else {
        handled = child.dispatchTouchEvent(ev);
    }
    return handled;
}

关键方法

  • dispatchTouchEvent:事件分发
  • onInterceptTouchEvent:事件拦截
  • onTouchEvent:事件处理

源码分析

Activity的分发起点

public boolean dispatchTouchEvent(MotionEvent ev) {
    if (ev.getAction() == MotionEvent.ACTION_DOWN) {
        onUserInteraction();
    }
    if (getWindow().superDispatchTouchEvent(ev)) {
        return true;
    }
    return onTouchEvent(ev);
}

实践应用

滑动冲突解决方案

  1. 外部拦截法
  2. 内部拦截法

示例代码

// 外部拦截法
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
    boolean intercepted = false;
    int x = (int) ev.getX();
    int y = (int) ev.getY();
    
    switch (ev.getAction()) {
        case MotionEvent.ACTION_DOWN:
            intercepted = false;
            break;
        case MotionEvent.ACTION_MOVE:
            if (父容器需要当前点击事件) {
                intercepted = true;
            } else {
                intercepted = false;
            }
            break;
        case MotionEvent.ACTION_UP:
            intercepted = false;
            break;
    }
    return intercepted;
}

面试题解析

Q1:事件传递的返回值的含义?

  • true:事件被消费,不再继续传递
  • false:事件未被消费,继续传递给父View的onTouchEvent

Q2:View的onTouchEvent默认返回值?

  • 可点击(clickable为true):返回true
  • 不可点击:返回false

Q3:事件分发的核心原理?

基于责任链模式,从顶层ViewGroup开始,逐层分发事件,直到找到合适的处理者。