Android事件传递机制

简介:
看了N篇事件传递机制的文章博客,用到的时候有些地方依然记不太清,不如自己动手。为了简单明了。没写那么多事。既当做自己的总结也当做笔记。go!
此Demo首先自定义了两个继承LinearLayout的ViewGroup,MyViewGroupA和MyViewGroupB.。一个继承View的MyView。MyViewGroupA 包裹MyViewGroupB 包裹MyView。详细可见代码。Demo下载
(1)MyViewGroupA
package com.dyk.view;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.widget.LinearLayout;

public class MyViewGroupA extends LinearLayout {

	public static final String TAG = "MainActivity";
	private static final String myViewGroupAContent = "MyViewGroupA";

	private Paint mPaint;

	public MyViewGroupA(Context context, AttributeSet attrs) {
		super(context, attrs);
		initView(context);
	}

	public MyViewGroupA(Context context) {
		this(context, null);
	}

	private void initView(Context context) {
		mPaint = new Paint();
		mPaint.setColor(Color.BLACK);
		mPaint.setAntiAlias(true);
		mPaint.setStyle(Style.FILL);
		mPaint.setTextSize(50f);
	}

	@Override
	protected void onDraw(Canvas canvas) {
		super.onDraw(canvas);
		canvas.drawText(myViewGroupAContent, 20, 50, mPaint);
	}

	@Override
	public boolean dispatchTouchEvent(MotionEvent ev) {
		Log.i(TAG, "MyViewGroupA dispatchTouchEvent action:" + ev.getAction());
		return super.dispatchTouchEvent(ev);
	}

	@Override
	public boolean onInterceptTouchEvent(MotionEvent ev) {
		Log.i(TAG,
				"MyViewGroupA onInterceptTouchEvent action:" + ev.getAction());
		return super.onInterceptTouchEvent(ev);
	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		Log.i(TAG, "MyViewGroupA onTouchEvent action:" + event.getAction());
		return super.onTouchEvent(event);
	}

}
(2) MyViewGroupB
package com.dyk.view;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.LinearLayout;

public class MyViewGroupB extends LinearLayout {

	public static final String TAG = "MainActivity";
	private static final String myViewGroupBContent="MyViewGroupB";
	
	private Paint mPaint;
	
	public MyViewGroupB(Context context) {
		this(context,null);
	}

	public MyViewGroupB(Context context, AttributeSet attrs) {
		super(context, attrs);
		initView(context);
	}
	
	private void initView(Context context) {
		mPaint = new Paint();
		mPaint.setColor(Color.BLACK);
		mPaint.setAntiAlias(true);
		mPaint.setStyle(Style.FILL);
		mPaint.setTextSize(50f);
	}
	
	@Override
	protected void onDraw(Canvas canvas) {
		super.onDraw(canvas);
		canvas.drawText(myViewGroupBContent, 20, 50, mPaint);
	}
	
	@Override
	public boolean dispatchTouchEvent(MotionEvent ev) {
		Log.i(TAG, "MyViewGroupB dispatchTouchEvent action:" + ev.getAction());
		return super.dispatchTouchEvent(ev);
	}
	
	@Override
	public boolean onInterceptTouchEvent(MotionEvent ev) {
		Log.i(TAG,
				"MyViewGroupB onInterceptTouchEvent action:" + ev.getAction());
		return super.onInterceptTouchEvent(ev);
	}
	
	@Override
	public boolean onTouchEvent(MotionEvent event) {
		Log.i(TAG, "MyViewGroupB onTouchEvent action:" + event.getAction());
		return super.onTouchEvent(event);
	}

	

}
(3)MyView
package com.dyk.view;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

public class MyView extends View {
	
	public static final String TAG = "MainActivity";
	private static final String myViewContent="MyView";

	private Paint mPaint;
	
	public MyView(Context context) {
		this(context, null);
	}

	public MyView(Context context, AttributeSet attrs) {
		this(context, attrs, 0);
	}

	public MyView(Context context, AttributeSet attrs, int defStyleAttr) {
		super(context, attrs, defStyleAttr);
		initView(context);
	}

	private void initView(Context context) {
		mPaint = new Paint();
		mPaint.setColor(Color.BLUE);
		mPaint.setAntiAlias(true);
		mPaint.setStyle(Style.FILL);
		mPaint.setTextSize(50f);
	}
	
	@Override
	protected void onDraw(Canvas canvas) {
		super.onDraw(canvas);
		Rect rect  = new Rect(0, 0, getWidth(), getHeight());
		canvas.drawRect(rect, mPaint);
		mPaint.setColor(Color.BLACK);
		canvas.drawText(myViewContent,20,50, mPaint);
	}
	
	@Override
	public boolean dispatchTouchEvent(MotionEvent event) {
		Log.i(TAG, "MyView dispatchTouchEvent action:" + event.getAction());
		return super.dispatchTouchEvent(event);
	}
	
	@Override
	public boolean onTouchEvent(MotionEvent event) {
		Log.i(TAG, "MyView onTouchEvent action:" + event.getAction());
		return super.onTouchEvent(event);
	}

}
(4)activity_main布局文件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#aaa"
    android:orientation="vertical" >

    <com.dyk.view.MyViewGroupA
        android:id="@+id/myViewGroupA"
        android:layout_width="match_parent"
        android:layout_height="300dp"
        android:background="#ff0000" >

        <com.dyk.view.MyViewGroupB
            android:id="@+id/myViewGroupB"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_margin="50dp"
            android:background="#00ff00"
            android:padding="50dp" >

            <com.dyk.view.MyView
                android:id="@+id/myView"
                android:layout_width="match_parent"
                android:layout_height="match_parent" >
            </com.dyk.view.MyView>
        </com.dyk.view.MyViewGroupB>
    </com.dyk.view.MyViewGroupA>

    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:text="mainActivity unUse place" />

</LinearLayout>
(4)MainActivity
package com.dyk.touchevent;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.MotionEvent;

public class MainActivity extends Activity {

	public static final String TAG = "MainActivity";

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
	}
	
	@Override
	public boolean dispatchTouchEvent(MotionEvent ev) {
		Log.i(TAG, "MainActivity dispatchTouchEvent action:" + ev.getAction());
		return super.dispatchTouchEvent(ev);
	}
	
	@Override
	public boolean onTouchEvent(MotionEvent event) {
		Log.i(TAG, "MainActivity onTouchEvent action:" + event.getAction());
		return super.onTouchEvent(event);
	}

}
     Activity有dispatchTouchEvent ()和onTouchEvent()方法,ViewGroup有 dispatchTouchEvent ()、onInterceptTouchEvent()和onTouchEvent()方法。其中onInterceptTouchEvent()为 拦截核心方法。View有dispatchTouchEvent ()和onTouchEvent()方法。dispatchTouchEvent()优先级大于onInterceptTouchEvent ()大于onTouchEvent ()。

没有更改任何返回值,正常情况:
1)单击MyViewGroupA :   MainActivity dispatchTouchEvent action:0---->
                       MyViewGroupA dispatchTouchEvent action:0---->
                       MyViewGroupA onInterceptTouchEvent action:0 ---->
                       MyViewGroupA onTouchEvent action:0---->
                       MainActivity onTouchEvent action:0 ---->
                       MainActivity dispatchTouchEvent action:1---->
                       MainActivity onTouchEvent action:1 .

2)单击MyViewGroupB :    MainActivity dispatchTouchEvent action:0---->  
                        MyViewGroupA dispatchTouchEvent action:0 ---->
                        MyViewGroupA onInterceptTouchEvent action:0 ---->
                        MyViewGroupB dispatchTouchEvent action:0 ---->
                        MyViewGroupB onInterceptTouchEvent action:0 ---->
                        MyViewGroupB onTouchEvent action:0 ---->
                        MyViewGroupA onTouchEvent action:0---->
                        MainActivity onTouchEvent action:0 ---->
                        MainActivity dispatchTouchEvent action:1---->
                        MainActivity onTouchEvent action:1 .

3)单击MyView       :    MainActivity dispatchTouchEvent action:0---->
                        MyViewGroupA dispatchTouchEvent action:0 ---->
                        MyViewGroupA onInterceptTouchEvent action:0 ---->
                        MyViewGroupB dispatchTouchEvent action:0 ---->
                        MyViewGroupB onInterceptTouchEvent action:0 ---->
                        MyView dispatchTouchEvent action:0 ---->
                        MyView onTouchEvent action:0 ---->
                        MyViewGroupB onTouchEvent action:0 ---->
                        MyViewGroupA onTouchEvent action:0---->
                        MainActivity onTouchEvent action:0 ---->
                        MainActivity dispatchTouchEvent action:1---->
                        MainActivity onT ouchEvent action:1 .

4)单击MainActivity  :  MainActivity dispatchTouchEvent action:0---->
                       MainActivity onTouchEvent action:0 ---->
                       MainActivity dispatchTouchEvent action:1---->
                       MainActivity onT ouchEvent action:1 .
:action:0代表MotionEvent.ACTION_DOWN,action:1 代表MotionEvent.ACTION_UP。
有关修改Activity:
     仅修改MainActivity中的dispatchTouchEvent()方法,使其返回值为true。可以发现,不论点击MyViewGroupA 、MyViewGroupB、MyView还是MainActivity的空白区域log输出都如下:
                                         MainActivity dispatchTouchEvent action:0---->
                                         MainActivity dispatchTouchEvent action:1---->
     仅修改MainActivity中的onTouchEvent()方法,使其返回值为true。因为MainActivity中的onTouchEvent()方法总是最后执行,所以看起来效果和 正常情况效果一样, :只是看起来一样。
有关修改MyViewGroupA:
     仅修改MyViewGroupA的 dispatchTouchEvent()方法,使其返回值为true。
1)单击MyViewGroupA :   MainActivity dispatchTouchEvent action:0---->
                       MyViewGroupA dispatchTouchEvent action:0---->
                       MainActivity dispatchTouchEvent action:1---->
                       MyViewGroupA dispatchTouchEvent action:1.

2)单击MyViewGroupB :   和单击MyViewGroupA效果一样

3)单击MyView       :   和单击MyViewGroupA效果一样

4)单击MainActivity :   MainActivity dispatchTouchEvent action:0---->
                       MainActivity onTouchEvent action:0 ---->
                       MainActivity dispatchTouchEvent action:1---->
                       MainActivity onT ouchEvent action:1 .
     仅修改MyViewGroupA的 onInterceptTouchEvent()方法,使其返回值为true。
1)单击MyViewGroupA :   MainActivity dispatchTouchEvent action:0---->
                       MyViewGroupA dispatchTouchEvent action:0---->
                       MyViewGroupA onInterceptTouchEvent action:0 ---->
                       MyViewGroupA onTouchEvent action:0---->
                       MainActivity onTouchEvent action:0 ---->
                       MainActivity dispatchTouchEvent action:1---->
                       MainActivity onTouchEvent action:1 .

2)单击MyViewGroupB :   和单击MyViewGroupA效果一样

3)单击MyView       :   和单击MyViewGroupA效果一样

4)单击MainActivity :   MainActivity dispatchTouchEvent action:0---->
                       MainActivity onTouchEvent action:0 ---->
                       MainActivity dispatchTouchEvent action:1---->
                       MainActivity onT ouchEvent action:1 .
   仅修改MyViewGroupA的 onTouchEvent ()方法,使其返回值为true。
1)单击MyViewGroupA :   MainActivity dispatchTouchEvent action:0---->
                       MyViewGroupA dispatchTouchEvent action:0---->
                       MyViewGroupA onInterceptTouchEvent action:0 ---->
                       MyViewGroupA onTouchEvent action:0---->
                       MainActivity dispatchTouchEvent action:1---->
                       MyViewGroupA dispatchTouchEvent action:1---->
                       MyViewGroupA onTouchEvent action:1

2)单击MyViewGroupB :   MainActivity dispatchTouchEvent action:0---->
                       MyViewGroupA dispatchTouchEvent action:0---->
                       MyViewGroupA onInterceptTouchEvent action:0 ---->
                       MyViewGroupB dispatchTouchEvent action:0 ---->
                       MyViewGroupB onInterceptTouchEvent action:0 ---->
                       MyViewGroupB onTouchEvent action:0 ---->
                       MyViewGroupA onTouchEvent action:0---->
                       MainActivity dispatchTouchEvent action:1---->
                       MyViewGroupA dispatchTouchEvent action:1---->
                       MyViewGroupA onTouchEvent action:1

3)单击MyView      :    MainActivity dispatchTouchEvent action:0---->
                       MyViewGroupA dispatchTouchEvent action:0---->
                       MyViewGroupA onInterceptTouchEvent action:0 ---->
                       MyViewGroupB dispatchTouchEvent action:0 ---->
                       MyViewGroupB onInterceptTouchEvent action:0 ---->
                       MyView dispatchTouchEvent action:0 ---->
                       MyView onTouchEvent action:0 ---->
                       MyViewGroupB onTouchEvent action:0 ---->
                       MyViewGroupA onTouchEvent action:0---->
                       MainActivity dispatchTouchEvent action:1---->
                       MyViewGroupA dispatchTouchEvent action:1---->
                       MyViewGroupA onTouchEvent action:1

4)单击MainActivity :   MainActivity dispatchTouchEvent action:0---->
                       MainActivity onTouchEvent action:0 ---->
                       MainActivity dispatchTouchEvent action:1---->
                       MainActivity onT ouchEvent action:1 .
有关修改MyView:
      仅修改MyView的 dispatchTouchEvent ()方法,使其返回值为true。
1)单击MyViewGroupA :   MainActivity dispatchTouchEvent action:0---->
                       MyViewGroupA dispatchTouchEvent action:0---->
                       MyViewGroupA onInterceptTouchEvent action:0 ---->
                       MyViewGroupA onTouchEvent action:0---->
                       MainActivity onTouchEvent action:0 ---->
                       MainActivity dispatchTouchEvent action:1---->
                       MainActivity onTouchEvent action:1 .

2)单击MyViewGroupB :   MainActivity dispatchTouchEvent action:0---->  
                       MyViewGroupA dispatchTouchEvent action:0 ---->
                       MyViewGroupA onInterceptTouchEvent action:0 ---->
                       MyViewGroupB dispatchTouchEvent action:0 ---->
                       MyViewGroupB onInterceptTouchEvent action:0 ---->
                       MyViewGroupB onTouchEvent action:0 ---->
                       MyViewGroupA onTouchEvent action:0---->
                       MainActivity onTouchEvent action:0 ---->
                       MainActivity dispatchTouchEvent action:1---->
                       MainActivity onTouchEvent action:1 .

3)单击MyView      :    MainActivity dispatchTouchEvent action:0---->
                       MyViewGroupA dispatchTouchEvent action:0 ---->
                       MyViewGroupA onInterceptTouchEvent action:0 ---->
                       MyViewGroupB dispatchTouchEvent action:0 ---->
                       MyViewGroupB onInterceptTouchEvent action:0 ---->
                       MyView dispatchTouchEvent action:0 ---->

                       MainActivity dispatchTouchEvent action:1---->
                       MyViewGroupA dispatchTouchEvent action:1 ---->
                       MyViewGroupA onInterceptTouchEvent action:1 ---->
                       MyViewGroupB dispatchTouchEvent action:1 ---->
                       MyViewGroupB onInterceptTouchEvent action:1 ---->
                       MyView dispatchTouchEvent action:1 ---->

4)单击MainActivity:    MainActivity dispatchTouchEvent action:0---->
                       MainActivity onTouchEvent action:0 ---->
                       MainActivity dispatchTouchEvent action:1---->
                       MainActivity onT ouchEvent action:1 .
    仅修改MyView的 onTouchEvent ()方法,使其返回值为true。
1)单击MyViewGroupA :   MainActivity dispatchTouchEvent action:0---->
                       MyViewGroupA dispatchTouchEvent action:0---->
                       MyViewGroupA onInterceptTouchEvent action:0 ---->
                       MyViewGroupA onTouchEvent action:0---->
                       MainActivity onTouchEvent action:0 ---->
                       MainActivity dispatchTouchEvent action:1---->
                       MainActivity onTouchEvent action:1 .

2)单击MyViewGroupB :   MainActivity dispatchTouchEvent action:0---->  
                       MyViewGroupA dispatchTouchEvent action:0 ---->
                       MyViewGroupA onInterceptTouchEvent action:0 ---->
                       MyViewGroupB dispatchTouchEvent action:0 ---->
                       MyViewGroupB onInterceptTouchEvent action:0 ---->
                       MyViewGroupB onTouchEvent action:0 ---->
                       MyViewGroupA onTouchEvent action:0---->
                       MainActivity onTouchEvent action:0 ---->
                       MainActivity dispatchTouchEvent action:1---->
                       MainActivity onTouchEvent action:1 .

3)单击MyView      :    MainActivity dispatchTouchEvent action:0---->
                       MyViewGroupA dispatchTouchEvent action:0 ---->
                       MyViewGroupA onInterceptTouchEvent action:0 ---->
                       MyViewGroupB dispatchTouchEvent action:0 ---->
                       MyViewGroupB onInterceptTouchEvent action:0 ---->
                       MyView dispatchTouchEvent action:0 ---->
                       MyView onTouchEvent action:0 ---->
                                        
                       MainActivity dispatchTouchEvent action:1---->
                       MyViewGroupA dispatchTouchEvent action:1 ---->
                       MyViewGroupA onInterceptTouchEvent action:1 ---->
                       MyViewGroupB dispatchTouchEvent action:1 ---->
                       MyViewGroupB onInterceptTouchEvent action:1 ---->
                       MyView dispatchTouchEvent action:1 ---->
                       MyView onTouchEvent action:1

4)单击MainActivity :   MainActivity dispatchTouchEvent action:0---->
                       MainActivity onTouchEvent action:0 ---->
                       MainActivity dispatchTouchEvent action:1---->
                       MainActivity onT ouchEvent action:1 .


事件传递(dispatchTouchEvent、onInterceptTouchEvent)的顺序是:MainActivity---->MyViewGroupA---->MyViewGroupB---->MyView
事件处理(onTouchEvent)的顺序是:MyView---->MyViewGroupB---->MyViewGroupA---->MainActivity

事件传递的返回值:true:拦截、不继续。false : 不拦截、继续。
事件处理的返回值:true:处理了,不用调用下级的onTouchEvent()。false : 没有处理,需要调用上级的onTouchEvent() 。











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

热门文章

最新文章