android事件分发和案例
来源:互联网 发布:小米windows平板3 编辑:程序博客网 时间:2024/06/01 12:51
1、事件分发
android控件层次嵌套关系(平级嵌套,父子嵌套)的视图关系,也就产生view(viewgroup)对触摸或者点击事件的消费关系,每一个控件都可以消费或者拒绝消费事件,在嵌套的布局中,关系可能更复杂些。android中的事件分发机制,保证我们想要的view获取到相应的事件。
view和viewgroup本质是做为view,但对于事件分发机制还是有很多区别,viewgroup可以做为view的载体,事件可能更复杂些。
1、ViewGroup中的分发机制三个方法
public boolean dispatchTouchEvent(MotionEvent ev); public boolean onInterceptTouchEvent(MotionEvent ev); public boolean onTouchEvent(MotionEvent ev);
2、View中的分发机制两个方法
public boolean dispatchTouchEvent(MotionEvent ev); public boolean onTouchEvent(MotionEvent ev);
3、Activity的回调方法
public boolean dispatchTouchEvent(MotionEvent ev); public boolean onTouchEvent(MotionEvent ev);
3、ViewGroup和View的事件分发
当我们触摸到Activity中的控件时,分发流程如下
ViewGroup里的onInterceptTouchEvent默认值是false这样才能把事件传给View里的onTouchEvent.ViewGroup里的onTouchEvent默认值是false。View里的onTouchEvent返回默认值是true.这样才能执行多次touch事件。
1、事件分发dispatchTouchEvent()
举例:LinearLayout
当TouchEvent发生时,首先Activity将TouchEvent传递给最顶层的View, TouchEvent最先到达最顶层 view 的 dispatchTouchEvent ,然后由 dispatchTouchEvent 方法进行分发,
如果dispatchTouchEvent返回true ,则交给这个view的onTouchEvent处理,如果dispatchTouchEvent返回 false ,则交给这个 view 的
interceptTouchEvent 方法来决定是否要拦截这个事件,
如果 interceptTouchEvent 返回 true ,也就是拦截掉了,则交给它的 onTouchEvent 来处理,如果 interceptTouchEvent 返回 false ,那么就传递给子 view ,由子 view 的 dispatchTouchEvent 再来开始这个事件的分发。如果事件传递到某一层的子 view 的 onTouchEvent 上了,这个方法返回了 false ,那么这个事件会从这个 view 往上传递,都是 onTouchEvent 来接收。而如果传递到最上面的 onTouchEvent 也返回 false 的话,这个事件就会“消失”,而且接收不到下一次事件。
在ViewGroup中
public boolean dispatchTouchEvent(MotionEvent ev){ ....//其他处理,在此不管 View[] views=getChildView(); for(int i=0;i<views.length;i++){ //判断下Touch到屏幕上的点在该子View上面 if(...){ if(views[i].dispatchTouchEvent(ev)) return true; } } ...//其他处理,在此不管 }
在View中
public boolean dispatchTouchEvent(MotionEvent ev){ ....//其他处理,在此不管 return onTouchEvent(event); }
2、事件处理onInterceptTouchEvent()
决定touch事件是否向下处理
1、如果onInterceptTouchEvent()返回true,代表当前ViewGroup消费了事件,不再向下传递touch事件 。因此事件会被当前控件的onTouchEvent()处理
2、如果onInterceptTouchEvent()返回false,代表当前ViewGroup没有处理事件,处理向下传递给子view(或者子viewgroup),这样touch事件又到子view的onInterceptTouchEvent()。
LinearLayoutonInterceptTouchEvent默认值是false这样才能把事件传给View里的onTouchEvent.
3、事件处理onTouchEvent()
onTouchEvent()用于处理事件(重点onTouch这个事件是从子控件回传到父控件的,一层层向下传),返回值决定当前控件是否消费(consume)了这个事件,也就是说在当前控件在处理完Touch事件后,是否还允许Touch事件继续向上(父控件)传递。返回false,则向上传递给父控件,详细一点就是这个touch事件就给了父控件,那么后面的up事件就是到这里touch触发,不会在传给它的子控件。如果父控件依然是false,那touch的处理就给到父控件的父控件,那么up的事件处理都在父控件的父控件,不会触发下面的。
ViewGroup里的onTouchEvent默认值是false。View里的onTouchEvent返回默认值是true.这样才能执行多次touch事件。
4、关于ViewGroup和View源码
ViewGroup中
1、在ViewGroup中dispatchTouchEvent()中默认返回false
2、dispatchTouchEvent()中返回false后,进入到onInterceptTouchEvent()方法中,默认返回false
public boolean onInterceptTouchEvent(MotionEvent ev) { if (ev.isFromSource(InputDevice.SOURCE_MOUSE) && ev.getAction() == MotionEvent.ACTION_DOWN && ev.isButtonPressed(MotionEvent.BUTTON_PRIMARY) && isOnScrollbarThumb(ev.getX(), ev.getY())) { return true; } return false; }
3、这样事件最终才传递给子vew的onTouchEvent()方法中。也就是定义的Linearlayout中的点击事件可以向下TextView,Button中传递
在View中
onTouchEvent默认返回true
也就是最终TextView,Button最终能够响应点击事件。
5、案例分析
当点击红包区域时,红包区域响应事件,点击外部蓝色时,外部响应
点击红包区域时,响应事件,外层不响应
外部区域:
package com.example.touchdemo;import android.content.Context;import android.graphics.Canvas;import android.util.AttributeSet;import android.util.Log;import android.view.MotionEvent;import android.widget.LinearLayout;/** * Created by yuxiaogang on 2017/4/5. */public class MyLinearLayout extends LinearLayout { public MyLinearLayout(Context context) { super(context); } public MyLinearLayout(Context context, AttributeSet attrs) { super(context, attrs); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); } @Override public boolean dispatchTouchEvent(MotionEvent ev) { Log.i("------ll outer", "***dispatchTouchEvent--start "); boolean b = super.dispatchTouchEvent(ev); Log.i("------ll outer", "***dispatchTouchEvent--end "+b); return true; }}
内部区域代码
package com.example.touchdemo;import android.content.Context;import android.graphics.Canvas;import android.util.AttributeSet;import android.util.Log;import android.view.MotionEvent;import android.widget.LinearLayout;/** * Created by yuxiaogang on 2017/4/5. */public class MyLinearLayoutInner extends LinearLayout { public MyLinearLayoutInner(Context context) { super(context); } public MyLinearLayoutInner(Context context, AttributeSet attrs) { super(context, attrs); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); } @Override public boolean dispatchTouchEvent(MotionEvent ev) { Log.i("------ll inner", "***dispatchTouchEvent--start "); boolean b = super.dispatchTouchEvent(ev); Log.i("------ll inner", "***dispatchTouchEvent--start "+b); return true; }}
参考博客
http://blog.csdn.net/xyz_lmn/article/details/12517911
- android事件分发和案例
- Android事件分发机制案例分析(一)
- android 中的事件分发和事件拦截
- android View事件分发和事件拦截
- Android事件分发机制(三)事件分发和消费
- android触摸事件的分发和处理
- android touch 事件分发和处理
- Android事件分发和消费机制总结
- Android之View和ViewGroup事件分发
- android 事件分发和消费机制
- Android事件分发原理和实例
- Android事件分发机制和一些疑问
- Android View事件分发和处理
- Android 事件的分发和消费机制
- Android事件分发机制学习和总结
- Android Touch事件分发和传递机制
- Android中的事件分发和处理
- Android 中的事件分发和处理
- 网页中android Toast效果的实现
- strchr的用法
- POJ 2151 Check the difficulty of problems (简单的概率dp)
- oralce redo
- 如何实现内存分配器?
- android事件分发和案例
- 前端学习总结
- 让脚本变成双击可执行
- Stm32 SWD 下载 调试配置
- WebSocket 是什么原理?为什么可以实现持久连接?
- Java中的mvc和三层结构究竟是什么关系
- Hibernate入门------HelloWord
- spring 方法注入 lookup方法注入
- JSP、Servlet中的路径问题