Android事件传递机制(二)deprecated
发布日期:2021-06-30 11:23:10 浏览次数:2 分类:技术文章

本文共 16087 字,大约阅读时间需要 53 分钟。

main.xml如下:

MainActivity如下:

package cn.c;import android.os.Bundle;import android.app.Activity;import android.view.MotionEvent;//Demo描述://分析Android事件分发和处理机制//总结://1 ViewGroup继承自View//  事件的传递方向为:从最外层(Activity)传递至最内层(某个View)//  事件的消费方向为:从最内层(某个View)传递至最外层(Activity)//  该两个方向是相反的//2 ViewGroup中事件处理的流程是://  dispatchTouchEvent->onInterceptTouchEvent->onTouchEvent//  View中事件处理的流程是://  dispatchTouchEvent->onTouchEvent//3 ViewGroup中onInterceptTouchEvent默认值是false//  表示未拦截//  ViewGroup中onTouchEvent默认值是false//  表示未消费//  View中onTouchEvent返回默认值是true//  表示已消费//测试方法://在界面中点击Button那么所展现流程和资料1中的图2基本一致 //为什么说基本一致呢?因为在MyButton中的onTouchEvent()方法默认返回的是true//即消费掉了事件所以只有在MyButton中的onTouchEvent()方法中执行,不会再回传到//MyLinearLayout和MyFrameLayout的onTouchEvent()方法.所以图2中关于onTouchEvent()//的回溯是不准确的.//测试结果://05-12 10:57:25.397: I/System.out(10133): ===> MainActivity 中调用 onCreate()//05-12 10:57:25.405: I/System.out(10133): --------------------------------------------------//05-12 10:57:28.835: I/System.out(10133): ===> MainActivity 中调用 dispatchTouchEvent()//05-12 10:57:28.835: I/System.out(10133): ===> super.dispatchTouchEvent()默认返回true//05-12 10:57:28.835: I/System.out(10133): --------------------------------------------------//05-12 10:57:28.835: I/System.out(10133): ===> MainActivity 中调用 onUserInteraction()//05-12 10:57:28.835: I/System.out(10133): --------------------------------------------------//05-12 10:57:28.835: I/System.out(10133): 外层MyFrameLayout 中调用  dispatchTouchEvent()//05-12 10:57:28.835: I/System.out(10133): super.dispatchTouchEvent()默认返回true 表示继续分发//05-12 10:57:28.835: I/System.out(10133): --------------------------------------------------//05-12 10:57:28.835: I/System.out(10133): 外层MyFrameLayout 中调用  onInterceptTouchEvent()//05-12 10:57:28.835: I/System.out(10133): super.onInterceptTouchEvent()默认返回false 表示不拦截//05-12 10:57:28.835: I/System.out(10133): --------------------------------------------------//05-12 10:57:28.835: I/System.out(10133): 内层MyLinearLayout 中调用  dispatchTouchEvent()//05-12 10:57:28.835: I/System.out(10133): super.dispatchTouchEvent()默认返回true 表示继续分发//05-12 10:57:28.835: I/System.out(10133): --------------------------------------------------//05-12 10:57:28.835: I/System.out(10133): 内层MyLinearLayout 中调用  onInterceptTouchEvent()//05-12 10:57:28.835: I/System.out(10133): super.onInterceptTouchEvent()默认返回false 表示不拦截//05-12 10:57:28.835: I/System.out(10133): --------------------------------------------------//05-12 10:57:28.835: I/System.out(10133): 自定义Button 中调用 dispatchTouchEvent()//05-12 10:57:28.835: I/System.out(10133): super.dispatchTouchEvent默认返回true//05-12 10:57:28.835: I/System.out(10133): --------------------------------------------------//05-12 10:57:28.835: I/System.out(10133): 自定义Button 中调用 onTouchEvent()--->ACTION_DOWN//05-12 10:57:28.835: I/System.out(10133): super.onTouchEvent()默认返回true//05-12 10:57:28.835: I/System.out(10133): --------------------------------------------------//05-12 10:57:28.858: I/System.out(10133): ===> MainActivity 中调用 dispatchTouchEvent()//05-12 10:57:28.858: I/System.out(10133): ===> super.dispatchTouchEvent()默认返回true//05-12 10:57:28.858: I/System.out(10133): --------------------------------------------------//05-12 10:57:28.858: I/System.out(10133): 外层MyFrameLayout 中调用  dispatchTouchEvent()//05-12 10:57:28.858: I/System.out(10133): super.dispatchTouchEvent()默认返回true 表示继续分发//05-12 10:57:28.858: I/System.out(10133): --------------------------------------------------//05-12 10:57:28.858: I/System.out(10133): 外层MyLinearLayout 中调用  onInterceptTouchEvent()//05-12 10:57:28.858: I/System.out(10133): super.onInterceptTouchEvent()默认返回false 表示不拦截//05-12 10:57:28.858: I/System.out(10133): --------------------------------------------------//05-12 10:57:28.858: I/System.out(10133): 内层MyLinearLayout 中调用  dispatchTouchEvent()//05-12 10:57:28.858: I/System.out(10133): super.dispatchTouchEvent()默认返回true 表示继续分发//05-12 10:57:28.858: I/System.out(10133): --------------------------------------------------//05-12 10:57:28.858: I/System.out(10133): 内层MyLinearLayout 中调用  onInterceptTouchEvent()//05-12 10:57:28.858: I/System.out(10133): super.onInterceptTouchEvent()默认返回false 表示不拦截//05-12 10:57:28.858: I/System.out(10133): --------------------------------------------------//05-12 10:57:28.858: I/System.out(10133): 自定义Button 中调用 dispatchTouchEvent()//05-12 10:57:28.858: I/System.out(10133): super.dispatchTouchEvent默认返回true//05-12 10:57:28.858: I/System.out(10133): --------------------------------------------------//05-12 10:57:28.858: I/System.out(10133): 自定义Button 中调用 onTouchEvent()--->ACTION_UP//05-12 10:57:28.858: I/System.out(10133): super.onTouchEvent()默认返回true//05-12 10:57:28.858: I/System.out(10133): --------------------------------------------------//结果分析://该结果为点击一次Button后的输出.展示了两次(down和up)完整的dispatchTouchEvent()过程//两次都是从最上层的Activity的dispatchTouchEvent()传递到了最下层的MyButton的//dispatchTouchEvent(),此时已到最下层,所以调用其最下层(即MyButton)的onTouchEvent//处理点击事件//假若想看到图2中onTouchEvent()的回溯,可将MyButton中onTouchEvent()//返回false.这样就可以看到一次完整的关于down事件的回溯.//测试结果如下://05-12 11:33:39.616: I/System.out(10657): ===> MainActivity 中调用 onCreate()//05-12 11:33:39.616: I/System.out(10657): --------------------------------------------------//05-12 11:33:46.436: I/System.out(10657): ===> MainActivity 中调用 dispatchTouchEvent()//05-12 11:33:46.436: I/System.out(10657): ===> super.dispatchTouchEvent()默认返回true//05-12 11:33:46.436: I/System.out(10657): --------------------------------------------------//05-12 11:33:46.436: I/System.out(10657): ===> MainActivity 中调用 onUserInteraction()//05-12 11:33:46.436: I/System.out(10657): --------------------------------------------------//05-12 11:33:46.436: I/System.out(10657): 外层MyFrameLayout 中调用  dispatchTouchEvent()//05-12 11:33:46.436: I/System.out(10657): super.dispatchTouchEvent()默认返回true 表示继续分发//05-12 11:33:46.436: I/System.out(10657): --------------------------------------------------//05-12 11:33:46.436: I/System.out(10657): 外层MyFrameLayout 中调用  onInterceptTouchEvent()//05-12 11:33:46.436: I/System.out(10657): super.onInterceptTouchEvent()默认返回false 表示不拦截//05-12 11:33:46.436: I/System.out(10657): --------------------------------------------------//05-12 11:33:46.436: I/System.out(10657): 内层MyLinearLayout 中调用  dispatchTouchEvent()//05-12 11:33:46.436: I/System.out(10657): super.dispatchTouchEvent()默认返回true 表示继续分发//05-12 11:33:46.436: I/System.out(10657): --------------------------------------------------//05-12 11:33:46.436: I/System.out(10657): 内层MyLinearLayout 中调用  onInterceptTouchEvent()//05-12 11:33:46.436: I/System.out(10657): super.onInterceptTouchEvent()默认返回false 表示不拦截//05-12 11:33:46.436: I/System.out(10657): --------------------------------------------------//05-12 11:33:46.436: I/System.out(10657): 自定义Button 中调用 dispatchTouchEvent()//05-12 11:33:46.436: I/System.out(10657): super.dispatchTouchEvent默认返回true//05-12 11:33:46.436: I/System.out(10657): --------------------------------------------------//05-12 11:33:46.436: I/System.out(10657): 自定义Button 中调用 onTouchEvent()--->ACTION_DOWN//05-12 11:33:46.436: I/System.out(10657): super.onTouchEvent()默认返回true//05-12 11:33:46.436: I/System.out(10657): --------------------------------------------------//05-12 11:33:46.436: I/System.out(10657): 内层MyLinearLayout 中调用  onTouchEvent()--->ACTION_DOWN//05-12 11:33:46.436: I/System.out(10657): super.onTouchEvent()默认返回false 表示未消费事件//05-12 11:33:46.436: I/System.out(10657): --------------------------------------------------//05-12 11:33:46.436: I/System.out(10657): 外层MyFrameLayout 中调用  onTouchEvent()--->ACTION_DOWN//05-12 11:33:46.436: I/System.out(10657): super.onTouchEvent()默认返回false 表示未消费事件//05-12 11:33:46.436: I/System.out(10657): --------------------------------------------------//05-12 11:33:46.436: I/System.out(10657): ===> MainActivity 中调用  onTouchEvent()--->ACTION_DOWN//05-12 11:33:46.436: I/System.out(10657): super.onTouchEvent()默认返回false 表示未消费事件//05-12 11:33:46.436: I/System.out(10657): --------至此一次完整的down的OnTouchEvent()回溯----------------//05-12 11:33:46.452: I/System.out(10657): ===> MainActivity 中调用 dispatchTouchEvent()//05-12 11:33:46.452: I/System.out(10657): ===> super.dispatchTouchEvent()默认返回true//05-12 11:33:46.452: I/System.out(10657): --------------------------------------------------//05-12 11:33:46.452: I/System.out(10657): ===> MainActivity 中调用  onTouchEvent()--->ACTION_MOVE//05-12 11:33:46.452: I/System.out(10657): super.onTouchEvent()默认返回false 表示未消费事件//05-12 11:33:46.452: I/System.out(10657): --------------------------------------------------//05-12 11:33:46.468: I/System.out(10657): ===> MainActivity 中调用 dispatchTouchEvent()//05-12 11:33:46.475: I/System.out(10657): ===> super.dispatchTouchEvent()默认返回true//05-12 11:33:46.475: I/System.out(10657): --------------------------------------------------//05-12 11:33:46.475: I/System.out(10657): ===> MainActivity 中调用  onTouchEvent()--->ACTION_UP//05-12 11:33:46.475: I/System.out(10657): super.onTouchEvent()默认返回false 表示未消费事件//05-12 11:33:46.475: I/System.out(10657): --------------------------------------------------//结果分析://为什么只有一次完整的down事件的onTouchEvent()的回溯而没有move事件和up事件相关的//onTouchEvent()的回溯??????//此时我们注意到从最上层(MainActvity)到最下层(MyButton)每一层的onTouchEvent()返回//的均为false.具体原因参见参考资料3//重要参考资料://1 http://www.eoeandroid.com/forum.php?mod=viewthread&tid=162460//  该资料中第二个图非常重要.//2 http://www.dewen.org/q/2438//  该资料中亦有流程图//3 http://blog.csdn.net/ponderforever/article/details/7082787//  在该资料的第四段提到://  如果事件传递到某一层的子 view的onTouchEvent上了,这个方法返回了 false,//  那么这个事件会从这个view往上传递,都是其对应的onTouchEvent来接收.//  而如果传递到最上面的onTouchEvent也返回 false的话,这个事件就会"消失",而且接收不到下一次事件.//  (我说的一次事件指的是 down 到 up 之间的一系列事件)//  针对该段最后一句话:(我说的一次事件指的是 down 到 up 之间的一系列事件)//  的补充说明:比如在此Demo的MainActivity的onTouchEvent()中返回false(即默认值)并且//  MyButton的onTouchEvent()也返回false(默认的是true)那么外层的MyFrameLayoue//  和内层的LinearLayout只能获取到down事件而move和up事件是不能获取的//  这点非常的重要.//4 http://blog.csdn.net/ddna/article/details/5473293//5 http://blog.csdn.net/ddna/article/details/5451722//6 http://www.sctarena.com/Article/Article.asp?nid=2802public class MainActivity extends Activity {    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.main);        System.out.println("===> MainActivity 中调用 onCreate()");        System.out.println("--------------------------------------------------");    }	    @Override    public boolean dispatchTouchEvent(MotionEvent ev) {    	System.out.println("===> MainActivity 中调用 dispatchTouchEvent()");		System.out.println("===> super.dispatchTouchEvent()默认返回true");		System.out.println("--------------------------------------------------");    	return super.dispatchTouchEvent(ev);    }	@Override	public void onUserInteraction() {		System.out.println("===> MainActivity 中调用 onUserInteraction()");		System.out.println("--------------------------------------------------");		super.onUserInteraction();	}		@Override	public boolean onTouchEvent(MotionEvent event) {		switch (event.getAction()) {		case MotionEvent.ACTION_DOWN:			System.out.println("===> MainActivity 中调用  onTouchEvent()--->ACTION_DOWN");			break;		case MotionEvent.ACTION_MOVE:			System.out.println("===> MainActivity 中调用  onTouchEvent()--->ACTION_MOVE");			break;		case MotionEvent.ACTION_UP:			System.out.println("===> MainActivity 中调用  onTouchEvent()--->ACTION_UP");		default:			break;		}		System.out.println("super.onTouchEvent()默认返回false 表示未消费事件");		System.out.println("--------------------------------------------------");		return super.onTouchEvent(event);	}	}

MyFrameLayout如下:

package cn.c;import android.content.Context;import android.util.AttributeSet;import android.view.MotionEvent;import android.widget.FrameLayout;public class MyFrameLayout extends FrameLayout{	public MyFrameLayout(Context context, AttributeSet attrs) {		super(context, attrs);	}	@Override	public boolean dispatchTouchEvent(MotionEvent ev) {		System.out.println("外层MyFrameLayout 中调用  dispatchTouchEvent()");		System.out.println("super.dispatchTouchEvent()默认返回true 表示继续分发");		System.out.println("--------------------------------------------------");		return super.dispatchTouchEvent(ev);		//return false;	}		//覆写自ViewGroup	@Override	public boolean onInterceptTouchEvent(MotionEvent ev) {		System.out.println("外层MyFrameLayout 中调用  onInterceptTouchEvent()");		System.out.println("super.onInterceptTouchEvent()默认返回false 表示不拦截");		System.out.println("--------------------------------------------------");		return super.onInterceptTouchEvent(ev);		//return true;	}	//注意:	//1 ViewGroup是View的子类	//2 ViewGroup中onTouchEvent()方法默认返回的是false	@Override	public boolean onTouchEvent(MotionEvent event) {		switch (event.getAction()) {		case MotionEvent.ACTION_DOWN:			System.out.println("外层MyFrameLayout 中调用  onTouchEvent()--->ACTION_DOWN");			break;		case MotionEvent.ACTION_MOVE:			System.out.println("外层MyFrameLayout 中调用  onTouchEvent()--->ACTION_MOVE");			break;		case MotionEvent.ACTION_UP:			System.out.println("外层MyFrameLayout 中调用  onTouchEvent()--->ACTION_UP");		default:			break;		}		System.out.println("super.onTouchEvent()默认返回false 表示未消费事件");		System.out.println("--------------------------------------------------");		return super.onTouchEvent(event);	}		}

MyLinearLayout如下:

package cn.c;import android.content.Context;import android.util.AttributeSet;import android.view.MotionEvent;import android.widget.LinearLayout;public class MyLinearLayout extends LinearLayout {	public MyLinearLayout(Context context, AttributeSet attrs) {		super(context, attrs);	}		@Override	public boolean dispatchTouchEvent(MotionEvent ev) {		System.out.println("内层MyLinearLayout 中调用  dispatchTouchEvent()");		System.out.println("super.dispatchTouchEvent()默认返回true 表示继续分发");		System.out.println("--------------------------------------------------");		return super.dispatchTouchEvent(ev);	}		//覆写自ViewGroup	@Override	public boolean onInterceptTouchEvent(MotionEvent ev) {		System.out.println("内层MyLinearLayout 中调用  onInterceptTouchEvent()");		System.out.println("super.onInterceptTouchEvent()默认返回false 表示不拦截");		System.out.println("--------------------------------------------------");		return super.onInterceptTouchEvent(ev);			}	//注意:	//1 ViewGroup是View的子类	//2 ViewGroup中onTouchEvent()方法默认返回的是false	@Override	public boolean onTouchEvent(MotionEvent event) {		switch (event.getAction()) {		case MotionEvent.ACTION_DOWN:			System.out.println("内层MyLinearLayout 中调用  onTouchEvent()--->ACTION_DOWN");			break;		case MotionEvent.ACTION_MOVE:			System.out.println("内层MyLinearLayout 中调用  onTouchEvent()--->ACTION_MOVE");			break;		case MotionEvent.ACTION_UP:			System.out.println("内层MyLinearLayout 中调用  onTouchEvent()--->ACTION_UP");		default:			break;		}		System.out.println("super.onTouchEvent()默认返回false 表示未消费事件");		System.out.println("--------------------------------------------------");		return super.onTouchEvent(event);	}		}

MyButton如下:

package cn.c;import android.content.Context;import android.util.AttributeSet;import android.view.MotionEvent;import android.widget.Button;public class MyButton extends Button{	public MyButton(Context context, AttributeSet attrs) {		super(context, attrs);	}		@Override	public boolean dispatchTouchEvent(MotionEvent event) {		System.out.println("自定义Button 中调用 dispatchTouchEvent()");		System.out.println("super.dispatchTouchEvent默认返回true");		System.out.println("--------------------------------------------------");		return super.dispatchTouchEvent(event);	}		//注意:	//在View的子类中onTouchEvent()方法默认返回的是true	@Override	public boolean onTouchEvent(MotionEvent event) {		switch (event.getAction()) {		case MotionEvent.ACTION_DOWN:			System.out.println("自定义Button 中调用 onTouchEvent()--->ACTION_DOWN");			break;		case MotionEvent.ACTION_MOVE:			System.out.println("自定义Button 中调用 onTouchEvent()--->ACTION_MOVE");			break;		case MotionEvent.ACTION_UP:			System.out.println("自定义Button 中调用 onTouchEvent()--->ACTION_UP");			break;		default:			break;		}		System.out.println("super.onTouchEvent()默认返回true");		System.out.println("--------------------------------------------------");		return super.onTouchEvent(event);	}		}

 

转载地址:https://it9527.blog.csdn.net/article/details/8921400 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:Android事件传递机制(一)deprecated
下一篇:Android事件传递机制(三)deprecated

发表评论

最新留言

感谢大佬
[***.8.128.20]2024年05月01日 05时13分46秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章