Android事件传递简介

本文深入解析了Android系统中事件的处理过程,包括事件的类型、传递机制、关键概念如MotionEvent、事件分发和消费等。通过图表展示事件传递过程,帮助读者理解Android事件系统的工作原理。


刚开始学Android时只知道复写那些方法,并没有去了解研究其中的原理过程。什么事件传递,分发,拦截等等。这里简单整理一下吧。

Android系统处理事件概述:

一、当用户触摸屏幕时,事件会被封装为一个MotionEvent对象。这个MotionEvent对象就用来描述用户的行为,

这其中的行为分类包括:

ACTION_DOWN   第一个点被按下

ACTION_UP     第一个点被抬起事件

ACTION_MOVE   当有点在屏幕上移动时触发

ACTION_CANCEL

ACTION_PIONTER_DOWN  :当屏幕上已经有一个点被按住,此时再按下其他点时触发。

ACTION_POINTER_UP    :当屏幕上有多个点被按住,松开其中一个点时触发(即非最后一个点被放开时)。


这一些事件构成。从用户行为组成来说包括三个要素:

touch location   :事件的位置

number of pointers(fingers) :事件源个数 ,比如几个手指 产生事件了

event time  : 事件发生的时间


二、events事件 开始与activity 中的dispatchTouchEvent(),并通过当前页面的view树结构逐层向下传递直到被消费掉为止,

最终任何没有被消费的事件都会传递到activity的ontouchEvent方法消费掉。

从viewgroup开始,一直传递给子view,最终到具体的某个view。这期间可以拦截这种传递过程。


三、到此我们可以分析到Android事件的传递过程:
1、首先从activity开始捕获事件,
然后分发事件给view树结构,也就是依附于当前window窗口的最顶层的view。sends event too root view attached         window.
如果activity分发的事件没有view消费掉事件的话,那么永远是activity的onTouchEvnet最后来消费掉这个事件。
        
2、然后在向view的分发过程中有这么一下两种情况。第一,按照树结构顺序从顶层view分发事件给带有OnTouchListen监听的view,(如果这个view写了监听的话)并由此view来决定事件是否要被消费掉。 第二:当前view如果没有消费事件,继续向下传递。



四、viewgroup中传递处理规则:

第一,首先检查是否复写了OnInterceptTouchEvent(),如果这个方法拦截了传递过程,那么这个viewgroup下面的子
view将接收不到传递的事件。
第二,如果接收到事件,那么依次遍历子view,并再次分发给子view,如果中间没有打断事件的传递那么就如此递归下去。

第三,当前viewgroup直接消费掉此事件,这时就和一个view性质类似了。

这里用一张图来表示Android系统中事件传递过程。


关于view中的事件传递,拦截或者事件被消费等等 如下图,我还是觉得图片说明比较清晰,直观.


-----------------------------------------------------------------------------------------------------------------



看懂图之后呢应该有对view的事件传递机制有了大致的了解了。具体怎么用还得根据具体的业务场景来定,我相信如果自己亲手写过几个稍微复杂点儿的自定义控件,那么这些知识点应该很熟悉了。


其他零散知识点:

ViewConfiguration :封装了用在自定义UI时用到的尺寸size,距离distance,等等常亮。
 
定义双击事件的间隔时间  
private static final int DOUBLE_TAP_TIMEOUT = 300;  
滑动距离的判断标准
private static final int TOUCH_SLOP = 16;  


TouchDelegate :可以使一个View 扩大触摸范围
 
Point   :封装坐标点


dispatchTouchEvent: 分发事件,我们可以在具体的需求中来定如何分发事件给子view。


分发事件给具体的某一个子view
getChildAt(0).dispatchTouchEvent(event);


分发事件给所有的子view
for (int i = 0; i < count; i++) {
View child = getChildAt(i);
try {
child.dispatchTouchEvent(event);
} catch (Exception e) {
e.printStackTrace();
}

}


使触摸事件定位与某一位置
  event.offsetLocation();
  event.setLocation(xxx);


	@Override
	public boolean onTouchEvent(MotionEvent event) {
		//Forward all touch events to the first child
		View child = getChildAt(0);
		if(child == null) {
			return false;
		}


        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            //Update this as the offset point
            mTouchOffsetPoint.x = (int)event.getX();
            mTouchOffsetPoint.y = (int)event.getY();
        }


        //Massage the event to be offset from the first touch
        event.offsetLocation(-mTouchOffsetPoint.x + child.getWidth() / 2,
                -mTouchOffsetPoint.y + child.getHeight() / 2);
	
	
		return child.dispatchTouchEvent(event);		
	}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值