Android事件传递小结

Android中的Touch事件

Android中的touch事件都封装在MotionEvent中,包括ACTION_UP, ACTION_DOWN, ACTION_MOVE等,处理touch事件的主要有三个方法

  • onTouchEvent(): 事件消费
  • dispatchTouchEvent(): 事件分发
  • onInterceptTouchEvent(): 事件拦截

这三个方法的返回值都是boolean类型的。

touch事件测试

首先建立三个嵌套的view,由内向外依次为TopView(红色), MiddleView(绿色)和BottomView(蓝色)

<com.test.toucheventdemo.ViewBottom
    android:layout_width="300dp"
    android:layout_height="300dp"
    android:background="@android:color/holo_blue_bright">

    <com.test.toucheventdemo.ViewMiddle
        android:layout_width="200dp"
        android:layout_height="200dp"
        android:background="@android:color/holo_green_light">

        <com.test.toucheventdemo.ViewTop
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:background="@android:color/holo_red_light"/>

    </com.test.toucheventdemo.ViewMiddle>

</com.test.toucheventdemo.ViewBottom>

然后重写每个view中的dispatchTouchEvent(), onTouchEvent()和onInterceptTouchEvent()这三个方法,用来查看每个方法被执行的情况。

@Override
public boolean dispatchTouchEvent(MotionEvent event) {
    return super.dispatchTouchEvent(event);
}

@Override
public boolean onTouchEvent(MotionEvent event) {
    Log.d("Touch", "bottom view->onTouchEvent");
    return super.onTouchEvent(event);
}

@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
    Log.d("Touch", "bottom view->onInterceptTouchEvent");
    return super.onInterceptTouchEvent(ev);
}

下面三个方法的返回值进行设定,查看不同效果 (1)默认情况,即三个方法都继承super的方法,运行后结果为

bottom view->onInterceptTouchEvent
middle view->onInterceptTouchEvent
top view->onInterceptTouchEvent
top view->onTouchEvent
middle view->onTouchEvent
bottom view->onTouchEvent

从结果可以看出touch事件是由外层向内传递的,onTouchEvent是由内向外执行的。默认情况下不对touch事件进行拦截,也不会对touch事件进行消费。

(2)事件拦截 将MiddleView的onInterceptTouchEvent()方法的返回值设为true,其余默认,即MiddleView会拦截touch事件,运行结果为

bottom view->onInterceptTouchEvent
middle view->onInterceptTouchEvent
middle view->onTouchEvent
bottom view->onTouchEvent

结果与预想一样,MiddleView拦截了touch事件,TopView并没有执行onTouchEvent()方法。

(3)事件分发 将MiddleView的dispatchTouchEvent()方法的返回值设为false,即在这一层不进行事件分发,运行结果为

bottom view->onInterceptTouchEvent
bottom view->onTouchEvent

结果说明只在底层进行了touch事件的处理,在上面两层并没有获取这个touch事件。 (3)事件消费 将MiddleView的onTouchEvent()返回值设为ture,对事件进行消费,运行结果为

bottom view->onInterceptTouchEvent
middle view->onInterceptTouchEvent
top view->onInterceptTouchEvent
top view->onTouchEvent
middle view->onTouchEvent
bottom view->onInterceptTouchEvent
middle view->onTouchEvent

可以看到一个奇怪的现象,middleView多执行了一次onTouchEvent()。将MiddleView的onTouchEvent()方法改写为

@Override
public boolean onTouchEvent(MotionEvent event) {
    Log.d("Touch MotionEvent", "MotionEvent->" + MotionEvent.actionToString(event.getAction()));
    Log.d("Touch", "middle view->onTouchEvent");
    return true;
}

这时在运行一次发现输出的结果为

bottom view->onInterceptTouchEvent
middle view->onInterceptTouchEvent
top view->onInterceptTouchEvent
top view->onTouchEvent
MotionEvent->ACTION_DOWN
middle view->onTouchEvent
bottom view->onInterceptTouchEvent
MotionEvent->ACTION_UP
middle view->onTouchEvent

MiddleView在ACTION_DOWN和ACTION_UP两个动作的时候都执行了一次onTouchEvent(),和之前默认情况多了一次执行,在未消费的情况下只监听到了ACTION_DOWN这个动作,说明如果ACTION_DOWN未消费的话,ACTION_UP也不会消费。

总结

(1) touch事件是由父View向子View传递的,消费的时候是由子View向父View传递的。
(2) 这三个方法执行优先级为dispatchTouchEvent()->onInterceptTouchEvent()->onTouchEvent()。
(3) 父View可以通过onInterceptTouchEvent()防止事件向后传递。
(4) onInterceptTouchEvent()可以将事件拦截在某一层,事件是可以在这一层被消费的;而dispatchTouchEvent()可以组织事件在某一层下发,在这一层无法被消费。
(5) onTouchEvent()中的ACTION_DOWN如果没有被消费,则ACTION_UP也不会被消费。

时间: 2025-01-19 12:39:46

Android事件传递小结的相关文章

Android事件传递机制

实验环境 OS X 10.9 Eclipse(ADT) Android源码版本:API Level 19(Android 4.4) Android事件构成 在Android中,事件主要包括点按.长按.拖拽.滑动等,点按又包括单击和 双击,另外还包括单指操作和多指操作.所有这些都构成了Android中的事件响应 .总的来说,所有的事件都由如下三个部分作为基础: 按下(ACTION_DOWN) 移动(ACTION_MOVE) 抬起(ACTION_UP) 所有的操作事件首先必须执行的是按下操作(ACT

Android事件传递机制(三)deprecated

main.xml如下: <!-- 自定义布局中,放置一个自定义控件 --> <cn.c.MyFrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" > <cn.c.MyLinearLayout

细说Android事件传递

一.View的dispatchTouchEvent和onTouchEvent 探讨Android事件传递机制前,明确android的两大基础控件类型:View和ViewGroup.View即普通的控件,没有子布局的,如Button.TextView. ViewGroup继承自View,表示可以有子控件,如Linearlayout.Listview这些.而事件即MotionEvent,最重要的有3个: (1)MotionEvent.ACTION_DOWN  按下View,是所有事件的开始 (2)M

Android事件传递机制_Android

实验环境 OS X 10.9 Eclipse(ADT) Android源码版本:API Level 19(Android 4.4) Android事件构成 在Android中,事件主要包括点按.长按.拖拽.滑动等,点按又包括单击和双击,另外还包括单指操作和多指操作.所有这些都构成了Android中的事件响应.总的来说,所有的事件都由如下三个部分作为基础: 按下(ACTION_DOWN) 移动(ACTION_MOVE) 抬起(ACTION_UP) 所有的操作事件首先必须执行的是按下操作(ACTIO

Android事件传递机制(零)

MainActivity如下: package com.cn; import android.app.Activity; import android.os.Bundle; import android.view.MotionEvent; import android.view.View; import android.view.View.OnTouchListener; /** * Demo描述: * http://blog.csdn.net/lfdfhl/article/details/89

Android事件传递机制(二)deprecated

main.xml如下: <!-- 自定义布局中,放置一个自定义控件 --> <cn.c.MyFrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" > <cn.c.MyLinearLayout

Android事件传递机制(四)deprecated

main.xml如下: <!-- 自定义布局中,放置一个自定义控件 --> <cn.c.MyFrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" > <cn.c.MyLinearLayout

Android事件传递机制(一)deprecated

main.xml如下: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools

Android事件传递机制(笔记)deprecated

总结: 1 事件的传递方向为:从最外层(Activity)传递至最内层(某个View)    事件的消费方向为:从最内层(某个View)传递至最外层(Activity)    该两个方向是相反的 2 ViewGroup中事件处理的流程是:    dispatchTouchEvent->onInterceptTouchEvent->onTouchEvent    View中事件处理的流程是:    dispatchTouchEvent->onTouchEvent    只有当前者返回tru