Android事件传递机制

原创 2016年05月30日 23:06:44

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来处理。






版权声明:本文为博主原创文章,未经博主允许不得转载。

android Touch事件传递机制

  • 2015年01月26日 17:33
  • 4.76MB
  • 下载

Android事件传递机制测试代码

  • 2014年03月30日 18:31
  • 1.41MB
  • 下载

Android事件传递机制、手势检测

领卓教育培训第七十三天 机制介绍分析我看了一篇博客,写的非常详细,而且通俗易懂! http://blog.csdn.net/morgan_xww/article/details/9372285/简单...

Android onTouch事件传递机制

  • 2017年02月28日 17:05
  • 27.68MB
  • 下载

Android事件传递机制

  • 2015年12月23日 19:44
  • 3.81MB
  • 下载

Android Touch事件传递机制详解 上

最近总是遇到关于Android Touch事件的问题,如:滑动冲突的问题,以前也花时间学习过Android Touch事件的传递机制,可以每次用起来的时候总是忘记了,索性自己总结一下写篇文章避免以后忘...

android 事件传递机制dome

  • 2016年02月25日 13:33
  • 7.56MB
  • 下载

Android TouchEvent事件传递机制

  • 2016年05月13日 14:14
  • 21.84MB
  • 下载

Android 事件的传递机制

感觉这里是Android中最麻烦,最绕的一个知识点了。博主心里现在心里有千万只草泥马在奔腾,着实不想整理啊,然而也就让它们稍微奔腾一会吧……    我们先通过一个例子,来了解一下什么是事件的传递:...

Android Touch事件传递机制解析

  • 2014年03月14日 17:38
  • 73KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Android事件传递机制
举报原因:
原因补充:

(最多只允许输入30个字)