Android事件分发详解(六)——ACTION_DOWN的消费验证

MainActivity如下:

package cn.c;
import android.os.Bundle;
import android.app.Activity;
import android.view.MotionEvent;

/**
 * Demo描述:
 * 分析Android事件分发和处理机制
 *
 * 在该示例中涉及到三个自定义的View.分别是:
 * 最外层的布局MyFrameLayout
 * 内层的布局MyLinearLayout
 * 最里层的自定义按钮MyButton
 *
 * 在dispatchTouchEvent()源码分析中提到一个很重要的东西:
 * 如果一个View没有处理ACTION_DOWN事件,即对于该事件返回了false(没有消费该事件)
 * 那么后续的ACTION_MOVE和ACTION_UP均不会再传递到该View;也就是说该View没有了
 * 处理ACTION_MOVE和ACTION_UP的资格.
 * 对于该问题,在此予以验证.
 *
 *
 * MyButton的onTouchEvent()方法中直接返回false.
 * 那么可以看到MyButton只处理了ACTION_DOWN.
 * 类似的MyFrameLayout和MyLinearLayout对于Touch事件也直接返回了false;他们也就处理不到
 * ACTION_MOVE和ACTION_UP
 *
 */

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) {
		super.dispatchTouchEvent(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);
	}
	//注意:
	//1 ViewGroup是View的子类
	//2 ViewGroup中onTouchEvent()方法默认返回的是false
	@Override
	public boolean onTouchEvent(MotionEvent event) {
		super.onTouchEvent(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);
		//return true;
	}

}

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) {
		super.dispatchTouchEvent(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) {
		super.onInterceptTouchEvent(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);
	}

	@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("--------------------------------------------------");
		//return false;
		return true;
	}

}

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>

时间: 2024-08-03 05:19:44

Android事件分发详解(六)——ACTION_DOWN的消费验证的相关文章

Android事件分发详解(五)——Touch事件传递验证

MainActivity如下: package cn.c; import android.os.Bundle; import android.app.Activity; import android.view.MotionEvent; /** * Demo描述: * 分析Android事件分发和处理机制 * * * 总结: * 1 ViewGroup继承自View * 事件的传递方向为:从最外层(Activity)传递至最内层(某个View) * 事件的消费方向为:从最内层(某个View)传递至

Android事件分发详解(四)——事件传递基础示例

MainActivity如下: package com.cn; import android.app.Activity; import android.os.Bundle; import android.view.MotionEvent; import android.view.View; import android.view.View.OnClickListener; import android.view.View.OnTouchListener; /** * Demo描述: * Andr

Android事件分发详解(三)——ViewGroup的dispatchTouchEvent()源码学习

package cc.aa; import android.os.Environment; import android.view.MotionEvent; import android.view.View; public class UnderstandDispatchTouchEvent { /** * dispatchTouchEvent()源码学习及其注释 * 常说事件传递中的流程是:dispatchTouchEvent->onInterceptTouchEvent->onTouchE

Android事件分发详解(一)——View的事件分发

MainActivity如下: package cc.cv; import android.os.Bundle; import android.view.MotionEvent; import android.view.View; import android.view.View.OnClickListener; import android.view.View.OnTouchListener; import android.widget.Button; import android.widge

Android Touch事件分发详解

Android Touch事件分发详解 先说一些基本的知识,方便后面分析源码时能更好理解. - 所有Touch事件都被封装成MotionEvent对象,包括Touch的位置.历史记录.第几个手指等. 事件类型分为ACTION_DOWN,ACTION_UP,ACTION_MOVE,ACTION_POINTER_DOWN,ACTION_POINTER_UP,ACTION_CANCEL, 每个 一个完整的事件以ACTION_DOWN开始ACTION_UP结束,并且ACTION_CANCEL只能由代码引

Android系统输入事件分发详解

什么是输入事件? 我们知道,运行android系统的设备本质上是一台计算机,使用者在和计算机进行交互的时候可以抽象成简单的对计算机的输入和输出(IO).那么对于运行在计算机上的操作系统来说,操作系统在与使用者进行交互的时候起始也是可以抽象成对外界的输入进行处理,然后在输出返还给使用者.本文只讨论的是android系统中的"输入事件"(因为本文讨论的都是输入事件,所以以下简称"输入事件"为"事件")相关的内容. 根据以上描述,我们就可以回答上面的问

Android事件流程详解

网络上有不少博客讲述了android的事件分发机制和处理流程机制,但是看过千遍,总还是觉得有些迷迷糊糊,因此特地抽出一天事件来亲测下,向像我一样的广大入门程序员详细讲述android事件背后的故事,话不多说,上干货. android整个事件流程主要牵扯到dispatchTouchEvent(),onInterceptTouchEvent(), onTouchEvent()这三个方法,下表来说明这三个方法的功能和分布场景: 表1: 方法名称 功解解说 Activity ViewGroup View

Android清单文件详解(六) ---- &lt;activity&gt;节点的属性

1.android:allowTaskReparenting android:allowTaskReparenting是一个任务调整属性,它表明当这个任务重新被送到前台时,该应用程序所定义的Activity是否可以从被启动的任务中转移到有相同亲和力的任务中. 看过前面博文都知道,讲解过这个属性,为什么在这里还要在提一次呢?因为它与<application>的android:allowTaskReparenting属性重叠,因此当为正在配置的Activity提供该属性的时候,它的默认值首先来自&

Android事件机制详解

TouchEvent事件研究 1.          Activity事件分析   dispatchTouchEvent onTouchEvent 执行结果 1 Super Super dispatchTouchEvent à onTouchEvent 2 false dispatchTouchEvent 3 true 2.          View and Activity事件分析 Activity view 执行结果 dispatchTouchEvent(1) onTouchEvent(2