本文主要是介绍android 事件机制,,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
view的事件机制:
不管是DOWN,MOVE,UP都会按照下面的顺序执行:
1、dispatchTouchEvent,(其中这个方法包括了setOnTouchListener(),还有onTouch()方法)
2、 setOnTouchListener的onTouchListener
3、onTouchEvent
分析:在dispatchTOucheEvent()首先判断mOnTouchListener不为null,并且view是enable的状态,然后 mOnTouchListener.onTouch(this, event)返回true,这三个条件如果都满足,直接return true ; 也就是不执行onTouchEvent(event);
(1)mOnTouchListener是否为null就的看他什么时候负值的,这个时候我们在源码中看到setOnTouchListener()
(2)ENABLED是判断当前点击的控件是否是enable的,按钮默认都是enable的,因此这个条件恒定为true。
(3) mOnTouchListener.onTouch(this, event),回调控件注册touch事件时的onTouch方法。也就是说如果我们在onTouch方法里返回 true,就会让这三个条件全部成立,从而整个方法直接返回true。如果我们在onTouch方法里返回false,就会再去执行 onTouchEvent(event)方法。
注:这里面就会出现你在代码中view.setOnTouchListener(new OnTouch(){ return true}),导致了你onTouchEvent(event)没执行了
onTouchEvent()方法中 就会去判断你的点击事件类型 比如长按还是点击,手指的操作类型,按下,移动,抬起,(对了这个里面点用了onclick()方法,这个需要知道)
(1) setEnable(false),CLICKABLE 都是在这个里面进行判断,false的话都会直接return false;
(2)onclick()方法在switch()中up情况下调用(先是调用performClick() ,onclick()就在这个方法中),这个方法其实就是 我们 长写的button.setOnClickListener(new OnClickListener(....))
ViewGroup事件分发:
分析:把ViewGroup看作一个View,一样执行上面view的3个循序,只是在dispatchTouchEvent()中多了一个事件拦截的步骤也就是disallowIntercept变量和onInterceptTouchEvent(ev)方法,他拦截之后就不给他下面的view或者viewGroup了,如果不拦截,就给传下去下面的view和viewGroup去处理事件 ,如果这些事件在view和viewGroup没有处理,那么会回传去,这个ViewGroup自己去处理事件,处理事件就是相当于view的事件了。。。
(1)如何拦截
@Override public boolean onInterceptTouchEvent(MotionEvent ev) { int action = ev.getAction(); switch (action) { case MotionEvent.ACTION_DOWN: //如果你觉得需要拦截 return true ; case MotionEvent.ACTION_MOVE: //如果你觉得需要拦截 return true ; case MotionEvent.ACTION_UP: //如果你觉得需要拦截 return true ; } return false; }
默认是不拦截的,即返回false;如果你需要拦截,只要return true就行了,这要该事件就不会往子View传递了,并且如果你在DOWN retrun true ,则DOWN,MOVE,UP子View都不会捕获事件;如果你在MOVE return true , 则子View在MOVE和UP都不会捕获事件。
原因很简单,当onInterceptTouchEvent(ev) return true的时候,会把mMotionTarget 置为null ;
(2)如何不被拦截
如果ViewGroup的onInterceptTouchEvent(ev) 当ACTION_MOVE时return true ,即拦截了子View的MOVE以及UP事件;
此时子View希望依然能够响应MOVE和UP时该咋办呢?
Android给我们提供了一个方法:requestDisallowInterceptTouchEvent(boolean) 用于设置是否允许拦截,我们在子View的dispatchTouchEvent中直接这么写:
@Override public boolean dispatchTouchEvent(MotionEvent event) { getParent().requestDisallowInterceptTouchEvent(true); int action = event.getAction(); switch (action) { case MotionEvent.ACTION_DOWN: Log.e(TAG, "dispatchTouchEvent ACTION_DOWN"); break; case MotionEvent.ACTION_MOVE: Log.e(TAG, "dispatchTouchEvent ACTION_MOVE"); break; case MotionEvent.ACTION_UP: Log.e(TAG, "dispatchTouchEvent ACTION_UP"); break; default: break; } return super.dispatchTouchEvent(event); }
getParent().requestDisallowInterceptTouchEvent(true); 这样即使ViewGroup在MOVE的时候return true,子View依然可以捕获到MOVE以及UP事件。 http://www.open-open.com/lib/view/open1462179977450.html
这篇关于android 事件机制,的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!