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:id="@+id/button"
		     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;
import android.widget.Button;
//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
//  表示已消费

//测试目标:
//将在外层MyFrameLayout中将事件跳过MyLinearLayout直接传递给MyButton

//测试方法:
//在MainActivity的dispatchTouchEvent方法中直接将事件指定给了MyButton
//比较简单,参见代码即可

//测试结果:
//05-13 11:33:04.639: I/System.out(20202): 自定义Button 中调用 dispatchTouchEvent()
//05-13 11:33:04.639: I/System.out(20202): super.dispatchTouchEvent默认返回true
//05-13 11:33:04.639: I/System.out(20202): --------------------------------------------------
//05-13 11:33:04.639: I/System.out(20202): 自定义Button 中调用 onTouchEvent()--->ACTION_DOWN
//05-13 11:33:04.639: I/System.out(20202): super.onTouchEvent()默认返回true
//05-13 11:33:04.639: I/System.out(20202): --------------------------------------------------
//05-13 11:33:04.655: I/System.out(20202): 自定义Button 中调用 dispatchTouchEvent()
//05-13 11:33:04.655: I/System.out(20202): super.dispatchTouchEvent默认返回true
//05-13 11:33:04.655: I/System.out(20202): --------------------------------------------------
//05-13 11:33:04.655: I/System.out(20202): 自定义Button 中调用 onTouchEvent()--->ACTION_UP
//05-13 11:33:04.655: I/System.out(20202): super.onTouchEvent()默认返回true
//05-13 11:33:04.655: I/System.out(20202): --------------------------------------------------


//重要参考资料:
//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 {
	private Button myButton;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        myButton=(Button) findViewById(R.id.button);
        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);
    	return myButton.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);
		//return false;
	}
	
	//覆写自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);
	}
	
	
}





 

相关文章
|
11天前
|
Swift UED
理解 Swift 事件传递和响应过程
【10月更文挑战第20天】事件传递和响应是 Swift 开发中不可或缺的部分,掌握其过程和机制对于构建高质量的应用至关重要。通过深入了解事件的产生、传递、响应者链的形成、响应者的选择和响应等环节,你能够更好地设计和实现交互功能,提升用户体验。同时,注意优化和避免常见问题,确保应用的性能和稳定性。
|
程序员 Scala 开发者
函数(方法)的调用机制|学习笔记
快速学习函数(方法)的调用机制。
函数(方法)的调用机制|学习笔记
|
开发工具 Android开发
RxBus 一个简易、非反射的Android事件通知库
RxBus 一个简易、非反射的Android事件通知库
783 0
RxBus 一个简易、非反射的Android事件通知库
|
缓存 小程序 Java
Java包装类、方法传参机制都有什么值得注意的?来自《卷Ⅰ》的灵魂提问(二)
Java包装类、方法传参机制都有什么值得注意的?来自《卷Ⅰ》的灵魂提问(二)
144 0
Java包装类、方法传参机制都有什么值得注意的?来自《卷Ⅰ》的灵魂提问(二)
|
缓存 Java 编译器
Java包装类、方法传参机制都有什么值得注意的?来自《卷Ⅰ》的灵魂提问(一)
Java包装类、方法传参机制都有什么值得注意的?来自《卷Ⅰ》的灵魂提问(一)
199 0
Java包装类、方法传参机制都有什么值得注意的?来自《卷Ⅰ》的灵魂提问(一)
|
监控 Java Android开发
【Android 电量优化】JobScheduler 相关源码分析 ( ConnectivityController 底层源码分析 | 构造函数 | 追踪任务更新 | 注册接收者监听连接变化 )
【Android 电量优化】JobScheduler 相关源码分析 ( ConnectivityController 底层源码分析 | 构造函数 | 追踪任务更新 | 注册接收者监听连接变化 )
194 0
事件监听机制的通俗解释
事件监听机制: A:事件源   事件发生的地方 B:事件      要发生的事情 C:事件处理    针对发生的事情做出的处理方案 D:事件监听    把事件源和事件关联起来 举例:人受伤事件。
912 0
|
Android开发 开发者