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

简介: MainActivity如下:package cn.c;import android.os.Bundle;import android.app.
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>


相关文章
|
2月前
|
Android开发
Android面试高频知识点(1) 图解Android事件分发机制
Android面试高频知识点(1) 图解Android事件分发机制
|
2月前
|
Android开发
Android面试高频知识点(1) 图解 Android 事件分发机制
Android面试高频知识点(1) 图解 Android 事件分发机制
46 1
|
2月前
|
XML 前端开发 Android开发
Android面试高频知识点(1) 图解Android事件分发机制
Android面试高频知识点(1) 图解Android事件分发机制
Android面试高频知识点(1) 图解Android事件分发机制
|
2月前
|
Android开发
Android 事件分发机制详细解读
Android 事件分发机制详细解读
45 5
|
4月前
|
图形学 Android开发
小功能⭐️Unity调用Android常用事件
小功能⭐️Unity调用Android常用事件
|
4月前
|
Android开发
Android面试高频知识点(1) 图解 Android 事件分发机制
在Android开发中,事件分发机制是一块Android比较重要的知识体系,了解并熟悉整套的分发机制有助于更好的分析各种点击滑动失效问题,更好去扩展控件的事件功能和开发自定义控件,同时事件分发机制也是Android面试必问考点之一,如果你能把下面的一些事件分发图当场画出来肯定加分不少。废话不多说,总结一句:事件分发机制很重要。
202 9
|
4月前
|
开发工具 Android开发
Android项目架构设计问题之组件A通知组件B某个事件的发生如何解决
Android项目架构设计问题之组件A通知组件B某个事件的发生如何解决
43 0
|
7月前
|
存储 算法 Android开发
AVB校验微观版本:android avb(Android Verified Boot)验证
AVB校验微观版本:android avb(Android Verified Boot)验证
1088 0
|
6月前
|
Android开发
39. 【Android教程】触摸事件分发
39. 【Android教程】触摸事件分发
49 2
|
6月前
|
XML Android开发 数据格式
37. 【Android教程】基于监听的事件处理机制
37. 【Android教程】基于监听的事件处理机制
93 2