Android事件分发的初识
来源:互联网 发布:分手炮内射 知乎 编辑:程序博客网 时间:2024/05/20 19:46
Android的事件分发的理论网络上已经有很多了,今天自己通过实例来深刻理解ViewGroup和View的事件分发,只有理解了其分发原理,就很容易处理平时遇到的滑动冲突的问题。
ViewGroup
首先看ViewGroup的事件分发:
自定义一个LinearLatout:
public class CustomLayout extends LinearLayout { private static final String TAG = "CustomLayout"; public CustomLayout(Context context) { super(context); } public CustomLayout(Context context, AttributeSet attrs) { super(context, attrs); } public CustomLayout(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); }}
第一步:拦截事件 onInterceptTouchEvent的返回值为true,则会调用OnTouchEvent事件
public class CustomLayout extends LinearLayout { private static final String TAG = "CustomLayout"; public CustomLayout(Context context) { super(context); } public CustomLayout(Context context, AttributeSet attrs) { super(context, attrs); } public CustomLayout(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override public boolean dispatchTouchEvent(MotionEvent ev) { Log.d(TAG, "dispatchTouchEvent: "); return super.dispatchTouchEvent(ev); } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { Log.d(TAG, "onInterceptTouchEvent: "); return true; } @Override public boolean onTouchEvent(MotionEvent event) { Log.d(TAG, "onTouchEvent: "); return super.onTouchEvent(event); }}
Debug的结果:
CustomLayout: dispatchTouchEvent:
CustomLayout: onInterceptTouchEvent:
CustomLayout: onTouchEvent:
第二步:不拦截事件 onInterceptTouchEvent的返回值为false
public class CustomLayout extends LinearLayout { private static final String TAG = "CustomLayout"; public CustomLayout(Context context) { super(context); } public CustomLayout(Context context, AttributeSet attrs) { super(context, attrs); } public CustomLayout(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override public boolean dispatchTouchEvent(MotionEvent ev) { Log.d(TAG, "dispatchTouchEvent: "); return super.dispatchTouchEvent(ev); } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { Log.d(TAG, "onInterceptTouchEvent: "); return false; } @Override public boolean onTouchEvent(MotionEvent event) { Log.d(TAG, "onTouchEvent: "); return super.onTouchEvent(event); }}
Debug结果:
CustomLayout: dispatchTouchEvent:
CustomLayout: onInterceptTouchEvent:
View
view作为一个单一的对象,当事件分发给它时,他只有处理和不处理两种选择,所以没有拦截事件。
第一种:如果注册了OnTouchlistener()监听事件,首先调用的是它的OnTouchListener(),如果它的返回值为True,则事件就会被消费掉;
public class CustomView extends Button { private static final String TAG = "CustomView"; public CustomView(Context context) { super(context); } public CustomView(Context context, AttributeSet attrs) { super(context, attrs); } public CustomView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override public boolean dispatchTouchEvent(MotionEvent event) { Log.d(TAG, "dispatchTouchEvent: "); return super.dispatchTouchEvent(event); } @Override public boolean onTouchEvent(MotionEvent event) { Log.d(TAG, "onTouchEvent: "); return true; }}
View注册了OnTouchListener()事件:
mCustomView.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { Log.d(TAG, "onTouch: "); return true; } });
Debug的结果:
CustomLayout: dispatchTouchEvent:
CustomLayout: onInterceptTouchEvent:
CustomView: dispatchTouchEvent:
DispatchEventActivity: onTouch:
从结果可以证明上面的结论,没有调用OnTouchEvent()。
第二种:如果没有注册OnTouchListener()监听事件,就会调用OnTouchEvent()方法,如果OnTouchEvent的返回值为True,则表示该View消费了该事件。
public class CustomView extends Button { private static final String TAG = "CustomView"; public CustomView(Context context) { super(context); } public CustomView(Context context, AttributeSet attrs) { super(context, attrs); } public CustomView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override public boolean dispatchTouchEvent(MotionEvent event) { Log.d(TAG, "dispatchTouchEvent: "); return super.dispatchTouchEvent(event); } @Override public boolean onTouchEvent(MotionEvent event) { Log.d(TAG, "onTouchEvent: "); return true; }}
Debug的结果:
CustomLayout: dispatchTouchEvent:
CustomLayout: onInterceptTouchEvent:
CustomView: dispatchTouchEvent:
CustomView: onTouchEvent:
结果可以证明直接回调用OnTouchEvent()方法。
第三种:如果注册了OnClickListener()监听事件,必须OnTouchEvent()返回值必须为父类的方法。
public class CustomView extends Button { private static final String TAG = "CustomView"; public CustomView(Context context) { super(context); } public CustomView(Context context, AttributeSet attrs) { super(context, attrs); } public CustomView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override public boolean dispatchTouchEvent(MotionEvent event) { Log.d(TAG, "dispatchTouchEvent: "); return super.dispatchTouchEvent(event); } @Override public boolean onTouchEvent(MotionEvent event) { Log.d(TAG, "onTouchEvent: "); return super.onTouchEvent(event); }}
mCustomView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Log.d(TAG, "onClick: "); } });
Debug的结果:
CustomLayout: dispatchTouchEvent:
CustomLayout: onInterceptTouchEvent:
CustomView: dispatchTouchEvent:
DispatchEventActivity: onTouch:
CustomView: onTouchEvent:
DispatchEventActivity: onClick:
第四种:OnTouchEvent()消费了该事件:
public class CustomView extends Button { private static final String TAG = "CustomView"; public CustomView(Context context) { super(context); } public CustomView(Context context, AttributeSet attrs) { super(context, attrs); } public CustomView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override public boolean dispatchTouchEvent(MotionEvent event) { Log.d(TAG, "dispatchTouchEvent: "); return super.dispatchTouchEvent(event); } @Override public boolean onTouchEvent(MotionEvent event) { Log.d(TAG, "onTouchEvent: "); return true; }}
Debug结果:
CustomLayout: dispatchTouchEvent:
CustomLayout: onInterceptTouchEvent:
CustomView: dispatchTouchEvent:
DispatchEventActivity: onTouch:
CustomView: onTouchEvent:
结果证明没有调用OnClickListener()。
由此得出的结论可以如下:
对于一个单一的View而言,事件的优先级为OnTouchListener()–OnTouchEvent()—OnClickListener();
- Android事件分发的初识
- 摘要android触摸事件的分发机制初识
- Android事件的分发
- android事件的分发
- Android的事件分发
- Android事件的分发
- Android的事件分发
- Android 事件的分发
- Android的事件分发
- Android的事件分发
- Android的事件分发
- android 的事件分发
- android-事件的分发 - 随心
- Android View的事件分发
- Android的事件分发(二)
- Android点击事件的分发
- android下的事件分发
- android事件分发的研究
- Python的基本输入输出
- 到底该不该用strip脱衣服
- PAT 1086. Tree Traversals Again
- 【单片机】51单片机最小系统
- 2031--进制转换
- Android事件分发的初识
- Android 解析 plist
- 适用于外查找的平衡树——B树
- Eclipse 下如何引用另一个项目的资源文件
- 连接mongodb,查询地理位置的问题
- 8款开源好用的网上电子商城系统介绍
- 移动端js触摸事件
- HDOJ N! Again 2674 同余
- day6 CodeForces 689B Mike and Shortcuts