Android事件传递机制(二)deprecated

简介: main.xml如下: MainActivity如下: package cn.c;import android.

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:layout_width="wrap_content"
        android:layout_height="wrap_content">
		   <cn.c.MyButton
		     android:layout_width="200dip"
		     android:layout_height="200dip"
		     android:text="自定义Button"
		     android:textColor="@android:color/black"
		   />
    </cn.c.MyLinearLayout>
</cn.c.MyFrameLayout>

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=2802


public 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);
	}
	
	
}






 

相关文章
|
1月前
|
开发框架 前端开发 Android开发
Flutter 与原生模块(Android 和 iOS)之间的通信机制,包括方法调用、事件传递等,分析了通信的必要性、主要方式、数据传递、性能优化及错误处理,并通过实际案例展示了其应用效果,展望了未来的发展趋势
本文深入探讨了 Flutter 与原生模块(Android 和 iOS)之间的通信机制,包括方法调用、事件传递等,分析了通信的必要性、主要方式、数据传递、性能优化及错误处理,并通过实际案例展示了其应用效果,展望了未来的发展趋势。这对于实现高效的跨平台移动应用开发具有重要指导意义。
160 4
|
7月前
|
前端开发 编译器 Android开发
构建高效Android应用:探究Kotlin协程的异步处理机制
【4月更文挑战第2天】在现代移动应用开发中,提供流畅且响应迅速的用户体验是至关重要的。随着Android平台的发展,Kotlin语言凭借其简洁性和功能性编程的特点成为了主流选择之一。特别地,Kotlin协程作为一种新型的轻量级线程管理机制,为开发者提供了强大的异步处理能力,从而显著提升了应用程序的性能和响应速度。本文将深入探讨Kotlin协程在Android中的应用,分析其原理、实现以及如何通过协程优化应用性能。
|
1月前
|
存储 安全 Android开发
探索Android与iOS的隐私保护机制
在数字化时代,移动设备已成为我们生活的一部分,而隐私安全是用户最为关注的问题之一。本文将深入探讨Android和iOS两大主流操作系统在隐私保护方面的策略和实现方式,分析它们各自的优势和不足,以及如何更好地保护用户的隐私。
|
2月前
|
消息中间件 存储 Java
Android消息处理机制(Handler+Looper+Message+MessageQueue)
Android消息处理机制(Handler+Looper+Message+MessageQueue)
45 2
|
1月前
|
Linux Android开发 iOS开发
深入探索Android与iOS的多任务处理机制
在移动操作系统领域,Android和iOS各有千秋,尤其在多任务处理上展现出不同的设计理念和技术实现。本文将深入剖析两大平台在后台管理、资源分配及用户体验方面的策略差异,揭示它们如何平衡性能与电池寿命,为用户带来流畅而高效的操作体验。通过对比分析,我们不仅能够更好地理解各自系统的工作机制,还能为开发者优化应用提供参考。
|
1月前
|
算法 Linux 调度
深入探索安卓系统的多任务处理机制
【10月更文挑战第21天】 本文旨在为读者提供一个关于Android系统多任务处理机制的全面解析。我们将从Android操作系统的核心架构出发,探讨其如何管理多个应用程序的同时运行,包括进程调度、内存管理和电量优化等方面。通过深入分析,本文揭示了Android在处理多任务时所面临的挑战以及它如何通过创新的解决方案来提高用户体验和设备性能。
45 1
|
2月前
|
消息中间件 存储 Java
Android面试高频知识点(2) 详解Android消息处理机制(Handler)
Android面试高频知识点(2) 详解Android消息处理机制(Handler)
|
2月前
|
消息中间件 存储 Java
Android面试高频知识点(2) 详解Android消息处理机制(Handler)
Android面试高频知识点(2) 详解Android消息处理机制(Handler)
61 1
|
2月前
|
存储 安全 数据安全/隐私保护
探索安卓与iOS的隐私保护机制####
【10月更文挑战第15天】 本文深入剖析了安卓和iOS两大操作系统在隐私保护方面的策略与技术实现,旨在揭示两者如何通过不同的技术手段来保障用户数据的安全与隐私。文章将逐一探讨各自的隐私控制功能、加密措施以及用户权限管理,为读者提供一个全面而深入的理解。 ####
85 1
|
2月前
|
消息中间件 存储 Java
Android消息处理机制(Handler+Looper+Message+MessageQueue)
Android消息处理机制(Handler+Looper+Message+MessageQueue)
66 2