返回

剖析Android事件分发机制二:层层传递,直至被消费

Android

Android事件分发机制原理回顾

在上一篇文章中,我们简单介绍了Android事件分发机制的原理,并总结出了事件分发机制的基本流程:事件从Activity的dispatchTouchEvent()方法开始传递,然后依次传递给ViewGroup的dispatchTouchEvent()方法和View的dispatchTouchEvent()方法,直到事件被消费或传递到最低层的View。

模拟事件分发过程

为了更好地理解事件分发机制,我们通过模拟一个简单的事件分发过程来演示事件是如何在View和ViewGroup之间传递和处理的。

假设我们有一个简单的布局,其中包含一个ViewGroup和一个View。ViewGroup的ID为“parent”,View的ID为“child”。

<LinearLayout
    android:id="@+id/parent"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <View
        android:id="@+id/child"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</LinearLayout>

现在,我们给“child”View添加一个移动事件,并打印出每个View和ViewGroup在处理事件时输出的日志信息。

View childView = findViewById(R.id.child);
childView.setOnTouchListener(new View.OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        Log.d("child", "onTouch: " + event);
        return false;
    }
});

ViewGroup parentView = findViewById(R.id.parent);
parentView.setOnTouchListener(new View.OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        Log.d("parent", "onTouch: " + event);
        return false;
    }
});

当我们手指触摸屏幕时,事件将首先传递到Activity的dispatchTouchEvent()方法,然后依次传递到ViewGroup的dispatchTouchEvent()方法和View的dispatchTouchEvent()方法。

在我们的例子中,输出的日志信息如下:

D/parent: onTouch: MotionEvent { action=ACTION_DOWN, pointers=[0], x=100.0, y=100.0, pressure=1.0, size=1.0, metaState=0, buttonState=0, edgeFlags=0, source=0x1002, flags=0x0 }
D/child: onTouch: MotionEvent { action=ACTION_DOWN, pointers=[0], x=100.0, y=100.0, pressure=1.0, size=1.0, metaState=0, buttonState=0, edgeFlags=0, source=0x1002, flags=0x0 }

从输出的日志信息中,我们可以看到,事件首先传递到了ViewGroup的dispatchTouchEvent()方法,然后传递到了View的dispatchTouchEvent()方法。

在我们的例子中,我们没有对事件进行消费,所以事件继续传递到了Activity的onTouchEvent()方法。

@Override
public boolean onTouchEvent(MotionEvent event) {
    Log.d("activity", "onTouchEvent: " + event);
    return super.onTouchEvent(event);
}

输出的日志信息如下:

D/activity: onTouchEvent: MotionEvent { action=ACTION_DOWN, pointers=[0], x=100.0, y=100.0, pressure=1.0, size=1.0, metaState=0, buttonState=0, edgeFlags=0, source=0x1002, flags=0x0 }

从输出的日志信息中,我们可以看到,事件最终传递到了Activity的onTouchEvent()方法。

总结

通过这个例子,我们对Android事件分发机制有了一个更深入的理解。我们了解到,事件从Activity的dispatchTouchEvent()方法开始传递,然后依次传递给ViewGroup的dispatchTouchEvent()方法和View的dispatchTouchEvent()方法,直到事件被消费或传递到最低层的View。

在实际开发中,我们可以根据需要对事件进行拦截和消费,以实现我们想要的效果。