项目源码

    public class MyLayout extends FrameLayout {        private static final String TAG = MyLayout.class.getName();        public MyLayout(Context context) {            super(context);        }        public MyLayout(Context context, AttributeSet attributeSet) {            super(context, attributeSet);        }        @Override        public boolean onInterceptTouchEvent(MotionEvent ev) {            Log.d(TAG, "MyLayout onInterceptTouchEvent() ");            return false;        }        @Override        public boolean onTouchEvent(MotionEvent event) {            Log.d(TAG, "MyLayout onTouchEvent() ");            LogEventUtil.logAction(event, TAG);            return true ;        }    }
    public class MyButton extends Button {        private static final String TAG = MyButton.class.getName();        public MyButton(Context context, AttributeSet attrs) {            super(context, attrs);        }        @Override        public boolean onTouchEvent(MotionEvent event) {            Log.d(TAG, "MyButton onTouchEvent " + super.onTouchEvent(event) );            LogEventUtil.logAction(event, TAG);            //return super.onTouchEvent(event);            return false;        }    }
    public class LogEventUtil {        public static void logAction(MotionEvent event, final String tag) {            int action = event.getAction();            switch(action) {                case MotionEvent.ACTION_DOWN:                    Log.d(tag, "Action down");                    break;                case MotionEvent.ACTION_CANCEL:                    Log.d(tag, "Action cancel");                    break;                case MotionEvent.ACTION_UP:                    Log.d(tag, "Action up");                    break;                case MotionEvent.ACTION_MOVE:                    Log.d(tag, "Action move");                    break;                default:                    Log.d(tag, "unknow action");            }        }    }

MyLayout(GroupView) 中方法的说明

 * public boolean onInterceptTouchEvent(MotionEvent ev)    默认调用 super.onInterceptTouchEvent(ev),该方法返回 false。不拦截TouchEvent * public boolean onTouchEvent(MotionEvent event)    默认调用 super.onTouchEvent(ev),该方法返回 false。

根据MyLayout , 运行实例说明,从 onInterceptTouchEvent 中进行说明

* Tag1 点击MyButton 运行路径,正常执行路径    1. D/com.kf.knowledge.accumulation.ui.event.MyLayout: MyLayout onInterceptTouchEvent()    2. D/com.kf.knowledge.accumulation.ui.event.MyButton: MyButton onTouchEvent    3. D/com.kf.knowledge.accumulation.ui.event.MyButton: Action down    4. D/com.kf.knowledge.accumulation.ui.event.MyLayout: MyLayout onInterceptTouchEvent()    5. D/com.kf.knowledge.accumulation.ui.event.MyButton: MyButton onTouchEvent    6. D/com.kf.knowledge.accumulation.ui.event.MyButton: Action up* Tag2 点击MyLayout区域,正常执行路径    1. D/com.kf.knowledge.accumulation.ui.event.MyLayout: MyLayout onInterceptTouchEvent()    2. D/com.kf.knowledge.accumulation.ui.event.MyLayout: MyLayout onTouchEvent() false    3. D/com.kf.knowledge.accumulation.ui.event.MyLayout: Action down* Tag3 点击MyButton ,修改 MyLayout中 onInterceptTouchEvent() 方法,返回 **true**,运行路径    1. D/com.kf.knowledge.accumulation.ui.event.MyLayout: MyLayout onInterceptTouchEvent()    2. D/com.kf.knowledge.accumulation.ui.event.MyLayout: MyLayout onTouchEvent() false    3. D/com.kf.knowledge.accumulation.ui.event.MyLayout: Action down

由上面运行实例,可以得知。MyLayout 装它的容器,的onInterceptTouchEvent 返回是true。
当 MyLayout 的方法 onInterceptTouchEvent 返回是默认情况false,则不拦截该事件的传递。
当 MyLayout 的方法 onInterceptTouchEvent 返回是true,MyButton进行拦截,在OnTouch 的 Down中消费了。

根据MyLayout , 运行实例说明,从onTouchEvent() 中进行说明

* MyButton 中 onTouchEvent() super.onTouchEvent(event) ,默认返回:true* MyLayout 中 onTouchEvent() super.onTouchEvent(event) ,默认返回:false* MyLayout 中 onInterceptTouchEvent() super.onInterceptTouchEvent() ,默认返回:false* Tag4 设定 MyLayout 中 onInterceptTouchEvent 返回 **true** , onTouchEvent() 返回 **true**    1. D/com.kf.knowledge.accumulation.ui.event.MyLayout: MyLayout onInterceptTouchEvent()    2. D/com.kf.knowledge.accumulation.ui.event.MyLayout: MyLayout onTouchEvent()    3. D/com.kf.knowledge.accumulation.ui.event.MyLayout: Action down    4. D/com.kf.knowledge.accumulation.ui.event.MyLayout: MyLayout onTouchEvent()    5. D/com.kf.knowledge.accumulation.ui.event.MyLayout: Action up    > 由这个实例可以得到,这个点击事件完全是给MyLayout消费了。* Tag5 MyLayout使用默认,MyButton onTouchEvent 返回**false**    1. D/com.kf.knowledge.accumulation.ui.event.MyLayout: MyLayout onInterceptTouchEvent()    2. D/com.kf.knowledge.accumulation.ui.event.MyButton: MyButton onTouchEvent true    3. D/com.kf.knowledge.accumulation.ui.event.MyButton: Action down    4. D/com.kf.knowledge.accumulation.ui.event.MyLayout: MyLayout onTouchEvent()    5. D/com.kf.knowledge.accumulation.ui.event.MyLayout: Action down    > 可以看到:容器没有拦截 -> 传递给控件 -> 控件使用了 onTouchEvent事件 -> 控件返回false,也就是不在消费该事件流了 ->        传递给容器 -> 容器同样返回false,也不消费其他事件流 -> 传递给上一层的容器 -> 都不消费 -> End* Tag6 MyLayout 消费事件。MyLayout onTouchEvent() 返回 **true** , MyButton onTouchEvent 返回**false**    1. D/com.kf.knowledge.accumulation.ui.event.MyLayout: MyLayout onInterceptTouchEvent()    2. D/com.kf.knowledge.accumulation.ui.event.MyButton: MyButton onTouchEvent true    3. D/com.kf.knowledge.accumulation.ui.event.MyButton: Action down    4. D/com.kf.knowledge.accumulation.ui.event.MyLayout: MyLayout onTouchEvent()    5. D/com.kf.knowledge.accumulation.ui.event.MyLayout: Action down    6. D/com.kf.knowledge.accumulation.ui.event.MyLayout: MyLayout onTouchEvent()    7. D/com.kf.knowledge.accumulation.ui.event.MyLayout: Action up    > 可以看到:容器没有拦截 -> 传递给控件 -> 控件使用了 onTouchEvent事件 ->     控件返回false,也就是不在消费该事件流了 ->传递给容器 -> 容器同样返回true,消费其他事件流 -> End

Android中点击传递事件的设计实现

* 点击MyLayout区域,这个流程可以看出。在API中实现的,所有都没有拦截,默认都不消费方法。* 一个正常的点击事件包括:ACTION_DOWN -> ACTION_MOVE -> ACTION_UP* **首先监测父类是否使用onInterceptTouchEvent拦截** ,如果拦截后,所有事件都在当前的容器中消费事件。* 全面理解事件传递的执行与消费    1. 容器拦截后,使用该事件,需要在onTouchEvent()中返回true,使用其所有事件。Tag4 运行事件中表现出来。


2. 容器拦截后,不使用该事件,需要在onTouchEvent()中返回false,那么只会消费 ACTION_DOWN事件。Tag3 运行事件中表现出来。

3. 容器不拦截,控件使用所有事件。Tag1 运行事件中表现出来。

4. 容器不拦截,控件不使用事件。Tag5 运行事件中表现出来。

5. 容器不拦截,容器控件消费事件。控件不消费事件。Tag6 运行事件中表现出来。

源码下载地址

https://github.com/forwardfly/AndroidAccumulation.git

更多相关文章

  1. Android错误汇总集锦
  2. android listview check 事件
  3. 2011.07.12——— android Foreground service
  4. Android(安卓)Webview 获取网页form 提交的数据
  5. android获取图库图片并返回
  6. Android(安卓)获取JSP或ASP的sessionId(Cookie)
  7. Android锁屏及监听锁屏事件
  8. Android(安卓)O 物理键盘和虚拟键盘同时支持
  9. Android(安卓)实现微信登录

随机推荐

  1. 【Android(安卓)Developers Training】 4
  2. Android(安卓)Material Design 之 Coordi
  3. Android(安卓)如何获取SDCard 内存(二)
  4. Android(安卓)创建文件路径这件事,你也可
  5. Android开发插件的下载与安装
  6. python服务器与android客户端socket通信
  7. Android麦克风录音的实现
  8. Android(安卓)studio中关于Spinner下拉列
  9. Android中判断手机是否联网实例
  10. Android(安卓)2.3.5 手动修改透明状态栏