本帖记录onInterceptTouchEvent和onTouchEvent调用关系,即各种return true和return false的运行情况。
return true和return false,代表的是是否消费完该事件,也就是该事件是否会继续传递给下层或者上层组件继续处理。return true代表消费完不会继续传递,return false代表没有消费完将会继续传递。
如果没有onInterceptTouchEvent,只考虑onTouchEvent的话,比较容易分析和理解。假如有三层布局结构,linearLayout1,linearLayout2,textView,从前到后是包含的关系。那么下面分情况说明。
1.
如果它们的onTouchEvent都返回false的话,DOWN事件会自上而下(textView位于最上层)依次传递,最终都没有消费完此事件,都
只会进入onTouchEvent方法一次并且MotionEvent的action为MotionEvent.ACTION_DOWN,move和up
等事件不会继续处理。
2.如果textView的onTouchEvent返回true,表示textView消费了此事件,不会传给父组件linearLayout2和linearLayout1了,并且还会继续处理move和up等事件。
3.linearLayout2和linearLayout1的onTouchEvent返回true和上面的情况一样,都不会继续传给父容器而且本身继续处理move和up等事件。
OK,这种情况还是比较容易理解的。
下面加入onInterceptTouchEvent。
onInterceptTouchEvent只有ViewGroup才会有,用于在进入自身onTouchEvent或者子组件onTouchEvent之前处理事件。注意onTouch是自上而下传递,而onInterceptTouch却是由下而上传递的。来了一个DOWN事件,首先进入的必然是最底层的viewGroup的onInterceptTouchEvent方法,然后根据return的值进入自身或者子组件的onTouch事件,当然如果子组件也是viewgroup的话,在进入子组件的onTouch之前也会进入子组件的onInterceptTouchEvent方法。
下面也分几种情况介绍:
1.当onInterceptTouchEvent返回false时,表示没有消费完此事件,会继续传递个子组件的onTouch继续处理。注意这种情况不会就不会传递给这个ViewGroup自身的onTouch事件处理了。这和onTouch如果返回false,后续的move、up等事件都不会继续处理了可以做同样理解。
2.当onInterceptTouchEvent返回true时,表示消费完此事件,或者说将在此组件上消费该事件。这种情况该事件会传递给ViewGroup自身的onTouch事件去处理,而不会传递给子组件的onTouch方法了。
由
此可以总结,onInterceptTouchEvent返回值只是决定了是要把事件传递给自身的onTouch事件还是传递给子组件的onTouch事
件。返回false表示没有消费完将传递个子组件的onTouch方法,返回true表示自身消费此事件,将传递给自身的onTouch方法而不会传递给
子组件的onTouch方法了。
流程图
阻止事件和分发事件:
1 6 public class MyLinearLayout extends LinearLayout { 7 8 9 public MyLinearLayout(Context context, AttributeSet attrs) { 10 super(context, attrs); 11 } 12 13 /** 14 * 中断事件 15 */ 16 @Override 17 public boolean onInterceptTouchEvent(MotionEvent ev) { 18 return true; 19 } 20 21 /** 22 * 分发事件 23 */ 24 @Override 25 public boolean dispatchTouchEvent(MotionEvent ev) { 26 return super.dispatchTouchEvent(ev); 27 } 28 29 /** 30 * 实现多个ListView控件同时触发事件 31 */ 32 @Override 33 public boolean onTouchEvent(MotionEvent event) { 34 35 int width=getWidth()/getChildCount(); 36 int height = getHeight(); 37 int count=getChildCount(); 38 39 float eventX = event.getX(); 40 41 if (eventX<width){ // 滑动左边的 listView 42 event.setLocation(width/2, event.getY()); 43 getChildAt(0).dispatchTouchEvent(event);//移动位置后,分发事件 44 return true; 45 46 } else if (eventX > width && eventX < 2 * width) { //滑动中间的 listView 47 float eventY = event.getY(); 48 if (eventY < height / 2) { 49 event.setLocation(width / 2, event.getY()); 50 for (int i = 0; i < count; i++) { 51 View child = getChildAt(i); 52 try { 53 child.dispatchTouchEvent(event); 54 } catch (Exception e) { 55 e.printStackTrace(); 56 } 57 58 } 59 return true; 60 } else if (eventY > height / 2) { 61 event.setLocation(width / 2, event.getY()); 62 try { 63 getChildAt(1).dispatchTouchEvent(event); 64 } catch (Exception e) { 65 e.printStackTrace(); 66 } 67 return true; 68 } 69 }else if (eventX>2*width){ 70 event.setLocation(width/2, event.getY()); 71 getChildAt(2).dispatchTouchEvent(event); 72 return true; 73 } 74 75 return true; 76 } 77 78 }