Android事件处理机制

    |     2015年9月8日   |   Android经验   |     0 条评论   |    2082

Android事件处理机制更准确的说应该叫 “Android事件分发、拦截、处理机制”。这里主要是针对Android中dispatchTouchEvent(分发TouchEvent), onInterceptTouchEvent(拦截TouchEvent), onTouchEvent(处理TouchEvent)事件的理解.


首先我们来认识下dispatchTouchEvent, onInterceptTouchEvent, onTouchEvent事件.

dispatchTouchEvent用于决定事件是否分发,当TouchEvent事件发生时,最先到达顶层Activity的dispatchTouchEvent方法,返回ture或false时事件被自身消费处理,返回super.dispatchTouchEvent(ev)(后面简称super)传递给下一层级dispatchTouchEvent方法处理.

onInterceptTouchEvent用于决定事件是否继续向下传递返回false或super时事件会传递给子View,返回值为true时事件不会继续传递给子View,事件将交给当前ViewGroup的onTouchEvent()处理,这就是所谓的Intercept(拦截)。

onTouchEvent用于处理事件(传递方向是从子View->父View),返回值决定当前控件是否消费(处理)了这个事件。返回值为true表示处理了当前事件,父View的OnTouchEvent事件将不会执行,返回值为false或super表示不处理当前事件交给父View的OnTouchEvent事件处理。

注:对于当前事件理解: 一次点击操作可能包含三个事件,按下事件(Down),移动事件(Move),弹起事件(up).
对于ACTION_DOWN事件,返回true,表示我想要处理后续事件;返回false,表示不关心此事件,并返回由父类进行处理。
特别注意ACTION_MOVE或者ACTION_UP发生的前提是一定曾经发生了ACTION_DOWN,如果你没有消费ACTION_DOWN,那么系统会认为ACTION_DOWN没有发生过,所以ACTION_MOVE或者ACTION_UP就不能被捕获。

我们看下示例:
布局如下

QQ截图20150908162106

<?xml version="1.0" encoding="utf-8"?>
<com.scxh.android1502.event.RootLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <com.scxh.android1502.event.TwotLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical" >

        <com.scxh.android1502.event.ChildTextView
            android:id="@+id/event_text"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="android事件处理机制" />

    </com.scxh.android1502.event.TwotLayout>

</com.scxh.android1502.event.RootLayout>

 

测试代码
public class RootLayout extends LinearLayout {

	public RootLayout(Context context, AttributeSet attrs) {
		super(context, attrs);
	}

	@Override
	public boolean onInterceptTouchEvent(MotionEvent ev) {
		Logs.d("RootLayout   onInterceptTouchEvent >>>>>>>");

		return false;
	}
	@Override
	public boolean onTouchEvent(MotionEvent event) {
		switch (event.getAction()) {
		case MotionEvent.ACTION_UP:
			Logs.i("RootLayout onTouchEvent 事件 ACTION_UP>>>>>>>>");
			break;
		case MotionEvent.ACTION_MOVE:
			Logs.v("RootLayout onTouchEvent 事件   ACTION_MOVE>>>>>>>>");
			break;
		case MotionEvent.ACTION_DOWN:
			Logs.d("RootLayout onTouchEvent 事件  ACTION_DOWN>>>>>>>>");
			break;
		}

		return true;
	}
}
public class TwotLayout extends LinearLayout {

	public TwotLayout(Context context, AttributeSet attrs) {
		super(context, attrs);
	}

	@Override
	public boolean onInterceptTouchEvent(MotionEvent ev) {
		Logs.i("TwotLayout   onInterceptTouchEvent >>>>>>>");

		return false;
	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		switch (event.getAction()) {
		case MotionEvent.ACTION_UP:
			Logs.i("TwotLayout onTouchEvent 事件 ACTION_UP>>>>>>>>");
			break;
		case MotionEvent.ACTION_MOVE:
			Logs.v("TwotLayout onTouchEvent 事件   ACTION_MOVE>>>>>>>>");
			break;
		case MotionEvent.ACTION_DOWN:
			Logs.d("TwotLayout onTouchEvent 事件  ACTION_DOWN>>>>>>>>");
			break;
		}

		return false;
	}

}
public class ChildTextView extends TextView {

	public ChildTextView(Context context, AttributeSet attrs) {
		super(context, attrs);
	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		switch (event.getAction()) {
		case MotionEvent.ACTION_UP:
			Logs.i("ChildTextView onTouchEvent 事件 ACTION_UP>>>>>>>>");
			break;
		case MotionEvent.ACTION_MOVE:
			Logs.v("ChildTextView onTouchEvent 事件   ACTION_MOVE>>>>>>>>");
			break;
		case MotionEvent.ACTION_DOWN:
			Logs.d("ChildTextView onTouchEvent 事件  ACTION_DOWN>>>>>>>>");
			break;
		}

		return true;
	}

}

1. 当RootLayout,TwoLayout的onInterceptTouchEvent事件返回false也就是不拦截且ChildTextView的onTouchEvent事件返回true消耗第一个Action_Down事件执行情况为:
QQ截图20150908162721
QQ截图20150908163419   QQ截图20150908163514

2.当RootLayout,TwoLayout的onInterceptTouchEvent事件返回false也就是不拦截且ChildTextView的onTouchEvent事件返回false不消耗第一个Action_Down事件执行情况为:
QQ截图20150908163649

QQ截图20150908163832 QQ截图20150908164027

 

 

事件传输机制更详细理解推荐kelin写的这编文章,http://www.jianshu.com/p/e99b5e8bd67b

这里贴张图.

966283-b9cb65aceea9219b

 

 

参考

细说Android事件传递机制(dispatchTouchEvent、onInterceptTouchEvent、onTouchEvent)

Android-onInterceptTouchEvent()和onTouchEvent()总结

Android中dispatchTouchEvent, onInterceptTouchEvent, onTouchEvent的理解

转载请注明来源:Android事件处理机制
回复 取消