Android事件传递机制

1、跟touch事件相关的三个方法:

用来分派event

public boolean dispatchTouchEvent(MotionEvent ev);


用来拦截event

public boolean onInterceptTouchEvent(MotionEvent ev);


用来处理event

public boolean onTouchEvent(MotionEventev);





2、三个方法的用法:

diapatchTouchEvent():用来分派事件,其中调用了onInterceptTouchEvent()onToucEvent(),一般不重写该方法。


OnInterceptTouchEvent():用来拦截事件。ViewGroup类中的源码实现就是{returnfalse;},表示不拦截该事件,事件将向下传递(传递给其子View);若手动重写该方法,使其返回true则表示拦截事件,事件将终止向下传递,事件有当前ViewGroup类来处理,就是调用该类的onTouchEvent()方法。


OnTouchEvent():用来处理事件。返回true则表示该View能处理该事件,事件将终止向上传递(传递给其父View);返回false表示不能处理,则把事件传递给其父ViewonTouchEvent()方法处理。


下面根据自己写的一个Demo进行具体的分析:

下面是该demo的布局效果图:







其代码如下:

Activity的布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
    
    <com.example.scrolllayouttest.MainLinearLayout
        android:layout_width="400dp"
        android:layout_height="400dp"
        android:background="#ffcc00">
        
        <com.example.scrolllayouttest.SubLinearLayout
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:background="#00cc00">
            
        </com.example.scrolllayouttest.SubLinearLayout>
    </com.example.scrolllayouttest.MainLinearLayout>

</LinearLayout>

Activity中的监听代码:

@Override
	public boolean onTouchEvent(MotionEvent event) {
		// TODO Auto-generated method stub
		switch (event.getAction()) {
		case MotionEvent.ACTION_DOWN:
			Log.i("Grament0524", " ActivityOne onTouchEvent  ACTION_DOWN");
			break;

		case MotionEvent.ACTION_MOVE:
			Log.i("Grament0524", "ActivityOne onTouchEvent  ACTION_MOVE");
			break;
		case MotionEvent.ACTION_UP:
			Log.i("Grament0524", "ActivityOne onTouchEvent  ACTION_UP");
			break;
		default:
			break;
		}
		return super.onTouchEvent(event);
	}

MainLinearLayout的监听代码:

@Override
	public boolean onInterceptTouchEvent(MotionEvent ev) {
		// TODO Auto-generated method stub
		switch (ev.getAction()) {
		case MotionEvent.ACTION_DOWN:
			Log.i("Grament0524", "MainLinearLayout onInterceptTouchEvent  ACTION_DOWN");
			break;

		case MotionEvent.ACTION_MOVE:
			Log.i("Grament0524", "MainLinearLayout onInterceptTouchEvent  ACTION_MOVE");
			break;
		case MotionEvent.ACTION_UP:
			Log.i("Grament0524", "MainLinearLayout onInterceptTouchEvent  ACTION_UP");
			break;
		default:
			break;
		}
		return super.onInterceptTouchEvent(ev);
//		return true;
		
	}
	
	@Override
	public boolean onTouchEvent(MotionEvent event) {
		// TODO Auto-generated method stub
		switch (event.getAction()) {
		case MotionEvent.ACTION_DOWN:
			Log.i("Grament0524", "MainLinearLayout onTouchEvent  ACTION_DOWN");
			break;

		case MotionEvent.ACTION_MOVE:
			Log.i("Grament0524", "MainLinearLayout onTouchEvent  ACTION_MOVE");
			break;
		case MotionEvent.ACTION_UP:
			Log.i("Grament0524", "MainLinearLayout onTouchEvent  ACTION_UP");
			break;
		default:
			break;
		}
		return super.onTouchEvent(event);
	//	return true;
	}

SubLinearLayout的监听代码:


@Override
	public boolean onInterceptTouchEvent(MotionEvent ev) {
		// TODO Auto-generated method stub
		switch (ev.getAction()) {
		case MotionEvent.ACTION_DOWN:
			Log.i("Grament0524", "SubLinearLayout onInterceptTouchEvent  ACTION_DOWN");
			break;

		case MotionEvent.ACTION_MOVE:
			Log.i("Grament0524", "SubLinearLayout onInterceptTouchEvent  ACTION_MOVE");
			break;
		case MotionEvent.ACTION_UP:
			Log.i("Grament0524", "SubLinearLayout onInterceptTouchEvent  ACTION_UP");
			break;
		default:
			break;
		}
		return super.onInterceptTouchEvent(ev);
	}
	
	@Override
	public boolean onTouchEvent(MotionEvent event) {
		// TODO Auto-generated method stub
		switch (event.getAction()) {
		case MotionEvent.ACTION_DOWN:
			Log.i("Grament0524", "SubLinearLayout onTouchEvent  ACTION_DOWN");
			break;

		case MotionEvent.ACTION_MOVE:
			Log.i("Grament0524", "SubLinearLayout onTouchEvent  ACTION_MOVE");
			break;
		case MotionEvent.ACTION_UP:
			Log.i("Grament0524", "SubLinearLayout onTouchEvent  ACTION_UP");
			break;
		default:
			break;
		}
		return super.onTouchEvent(event);
	//	return true;
	}

情景一:

可以看到现在所有的事件的传递函数都是默认返回super.onInterceptTouchEvent(ev)或者返回super.onTouchEvent(event);就是表示都不拦截,不处理事件。

运行程序,查看打印的Log信息:


可以分析,按下的ACTION_DOWN事件先是传递到MainLinearLayoutonInterceptTouchEvent中判断是否进行拦截,不拦截则会传递子ViewSubLinearLayout中,在SubLinearLayout中的onInterceptTouchEvent判断是否拦截,不拦截。由于传递到了最后一个View了,所以先由最后一个ViewonTouchEvent进行判断,是否处理该事件,由于是SubLinearLayout返回super.onTouchEvent(event),表示不处理,所以事件继续向上传递;由于MainLinearLayoutonTouchEvent返回的是super.onTouchEvent(event),表示不处理,所以事件继续向上传递;由于没有子View消费该事件,所以事件最后传递到ActivityonTouchEvent中,由Activity进行处理该事件。

情景二:


MainLinearLayout中的监听代码改为:

@Override
	public boolean onInterceptTouchEvent(MotionEvent ev) {
		// TODO Auto-generated method stub
		switch (ev.getAction()) {
		case MotionEvent.ACTION_DOWN:
			Log.i("Grament0524", "MainLinearLayout onInterceptTouchEvent  ACTION_DOWN");
			break;

		case MotionEvent.ACTION_MOVE:
			Log.i("Grament0524", "MainLinearLayout onInterceptTouchEvent  ACTION_MOVE");
			break;
		case MotionEvent.ACTION_UP:
			Log.i("Grament0524", "MainLinearLayout onInterceptTouchEvent  ACTION_UP");
			break;
		default:
			break;
		}
	//	return super.onInterceptTouchEvent(ev);
		return true;
		
	}
	
	@Override
	public boolean onTouchEvent(MotionEvent event) {
		// TODO Auto-generated method stub
		switch (event.getAction()) {
		case MotionEvent.ACTION_DOWN:
			Log.i("Grament0524", "MainLinearLayout onTouchEvent  ACTION_DOWN");
			break;

		case MotionEvent.ACTION_MOVE:
			Log.i("Grament0524", "MainLinearLayout onTouchEvent  ACTION_MOVE");
			break;
		case MotionEvent.ACTION_UP:
			Log.i("Grament0524", "MainLinearLayout onTouchEvent  ACTION_UP");
			break;
		default:
			break;
		}
    <span style="font-family:Droid Sans;">//</span>          return super.onTouchEvent(event);
		return true;
	}

表示MainLinearLayout拦截该事件(在onInterceptTouchEvent中返回true),并且处理该事件(在onTouchEvent中返回true)。



根据其Log,可以分析,事件先是传递到MainLinearLayoutonInterceptTouchEvent中判断是否需要拦截该事件,由于是返回true,所以MainLinearLayout拦截了事件,事件就交由MainLinearLayoutonTouchEvent进行事件的处理了;在MainLinearLayoutonTouchEvent中,由于是返回了true,表示能处理该事件,所以后面的ACTION_MOVE,ACTION_UP都交由MainLinearLayoutonTouchEvent来处理。






阅读更多
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Garment1991/article/details/51541930
文章标签: android
个人分类: Android开发
上一篇自定义时间选择器DatePicker
下一篇微信小程序的学习(1)
想对作者说点什么? 我来说一句

Android Touch事件传递机制解析

2014年03月14日 73KB 下载

Android TouchEvent事件传递机制

2016年05月13日 21.84MB 下载

onTouch测试

2017年02月28日 27.23MB 下载

Android onTouch事件传递机制

2017年02月28日 27.68MB 下载

android Touch事件传递机制

2015年01月26日 4.76MB 下载

没有更多推荐了,返回首页

关闭
关闭