Android图解浅析事件拦截机制

布局文件如下:


<RelativeLayout 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"

    tools:context="com.example.viewdispatch.MainActivity" >



    <com.example.views.MyViewGroupA

        android:layout_width="260dp"

        android:layout_height="360dp"

        android:background="#f42c61" >



        <com.example.views.MyViewGroupB

            android:layout_width="200dp"

            android:layout_height="300dp"

            android:background="#042c61" >



            <com.example.views.MyView

                android:layout_width="160dp"

                android:layout_height="260dp"

                android:background="#cccccc" />

        </com.example.views.MyViewGroupB>

    </com.example.views.MyViewGroupA>



</RelativeLayout>

整体的Activity包含3个自定义的View,项目结构是MyView、MyViewGroupB、MyViewGroupA。所以整体Touch事件的主角是View和ViewGroup,而与View相关的Touch事件有2个dispatchTouchEvent和onTouchEvent;与ViewGroup相关的Touch事件有3个dispatchTouchEvent,onInterceptTouchEvent,onTouchEvent。所以我们在定义好View和ViewGroup后,让其分别是实现这些方法。

代码如下:

MyView.java


import android.content.Context;

import android.util.AttributeSet;

import android.util.Log;

import android.view.MotionEvent;

import android.view.View;



public class MyView extends View {

	private String Tag = "MyView";



	public MyView(Context context, AttributeSet attrs, int defStyleAttr) {

		super(context, attrs, defStyleAttr);

	}



	public MyView(Context context, AttributeSet attrs) {

		super(context, attrs);

		Log.d(Tag, "----->MyView");

	}



	@Override

	public boolean onTouchEvent(MotionEvent event) {

		Log.e(Tag, "----->onTouchEvent");

		return super.onTouchEvent(event);

	}



	@Override

	public boolean dispatchTouchEvent(MotionEvent event) {

		Log.e(Tag, "----->dispatchTouchEvent");

		return super.dispatchTouchEvent(event);



	}



}



MyViewGroupA.java```

import android.content.Context;

import android.util.AttributeSet;

import android.util.Log;

import android.view.MotionEvent;

import android.view.ViewGroup;

import android.widget.LinearLayout;

public class MyViewGroupA extends LinearLayout {

private String Tag = "MyViewGroupA";



public MyViewGroupA(Context context, AttributeSet attrs, int defStyleAttr) {

	super(context, attrs, defStyleAttr);

	// TODO 自动生成的构造函数存根

}



public MyViewGroupA(Context context, AttributeSet attrs) {

	super(context, attrs);

	Log.d(Tag, "----->MyViewGroupA");

}



@Override

public boolean dispatchTouchEvent(MotionEvent ev) {

	Log.e(Tag, "----->dispatchTouchEvent");

	return super.dispatchTouchEvent(ev);

}



@Override

public boolean onInterceptTouchEvent(MotionEvent ev) {

	Log.e(Tag, "----->onInterceptTouchEvent");

	return super.onInterceptTouchEvent(ev);

}



@Override

public boolean onTouchEvent(MotionEvent event) {

	Log.e(Tag, "----->onTouchEvent");

	return super.onTouchEvent(event);

}

}


MyViewGroupB和A一样,就不贴了。



其中上面事件的传递的返回值是这样的,如果返回true,表示该View(ViewGroup)拦截了,不继续往下分发事件了,如果返回false,表示不拦截,继续往下分发。默认的调用父方法super.xxx是表示不拦截的意思。



下面就开始来验证吧。



运行我们的项目,先看看我们3个view的加载情况吧:



![](https://img-blog.csdn.net/20160901212758988?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)  



可以看出是由外到内加载的。



好了,开始touch事件吧,现在我们先点击最外层粉红的ViewGroupA,观察Log输出:



![](https://img-blog.csdn.net/20160901212619675?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)  



然后点击蓝色区域的ViewGroupB,再观察Log输出:



![](https://img-blog.csdn.net/20160901213030763?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)  

最后点击MyView观察输出



![](https://img-blog.csdn.net/20160901213115358?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)  



由此,我们可以大致的绘制出如下图所示的这样的一个图解流程。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值