android 全方位理解TouchEvent
来源:互联网 发布:360比价软件 编辑:程序博客网 时间:2024/05/29 02:32
关于TouchEvent涉及下面三个方法:
public boolean dispatchTouchEvent(MotionEvent ev); //分派event
public boolean onInterceptTouchEvent(MotionEvent ev); //拦截event
public boolean onTouchEvent(MotionEvent ev); //处理event
先不管dispatchTouchEvent如何分派,先运行代码测试效果。
activity_main.xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".MainActivity" android:id = "@+id/layout"> <com.example.test.MyLinearLayout android:layout_width="match_parent" android:layout_height="match_parent"> <com.example.test.MyButton android:layout_width="wrap_content" android:layout_height="wrap_content" android:text = "@string/button"/> </com.example.test.MyLinearLayout></RelativeLayout>
MainActivity.java:
public class MainActivity extends Activity {public static final String TAG = "MainActivity"; @Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);}@Overridepublic boolean onTouchEvent(MotionEvent event) {Log.e(TAG, "MainActivity onTouchEvent default return " + super.onTouchEvent(event)); return super.onTouchEvent(event);}}
MyLinearLayout.java:
public class MyLinearLayout extends LinearLayout {public static final String TAG = "MyLinearLayout";public MyLinearLayout(Context context, AttributeSet attrs) {super(context, attrs);// TODO Auto-generated constructor stub}@Overridepublic boolean onInterceptTouchEvent(MotionEvent ev) {// TODO Auto-generated method stubLog.e(TAG, "MyLinearLayout onInterceptTouchEvent default return " + super.onInterceptTouchEvent(ev));return super.onInterceptTouchEvent(ev);}@Overridepublic boolean onTouchEvent(MotionEvent event) {// TODO Auto-generated method stubLog.e(TAG, "MyLinearLayout onTouchEvent default return " + super.onTouchEvent(event));return super.onTouchEvent(event);}}
MyButton.java:
public class MyButton extends Button{public static final String TAG = "MyButton";public MyButton(Context context, AttributeSet attrs) {super(context, attrs);// TODO Auto-generated constructor stub}@Overridepublic boolean onTouchEvent(MotionEvent event) {Log.e(TAG, "MyButton onTouchEvent default return " + super.onTouchEvent(event));return super.onTouchEvent(event);}}
效果为:
点击按钮后,首先产生MotionEvent.ACTION_DOWN事件,MyLinearLayout的onInterceptTouchEvent方法尝试截取event,由于default return false(不截取),轮到MyButton处理,default return true处理成功,完成。然后还会产生MotionEvent.ACTION_UP事件,同样的过程。
注意:MyLinearLayout的onInterceptTouchEvent是继承与ViewGroup的onInterceptTouchEvent,而onTouchEvent是继承与View的onTouchEvent;而MyButton的onTouchEvent是继承与TextView的onTouchEvent。所以他们的default return不一样。
如果使MyButton中的onTouchEvent返回false。情况会如何呢?MyButton的onTouchEvent代码改成下面:
@Overridepublic boolean onTouchEvent(MotionEvent event) {Log.e(TAG, "MyButton onTouchEvent return false");return false;}
同样的,点击按钮后,首先产生MotionEvent.ACTION_DOWN事件,MyLinearLayout的onInterceptTouchEvent方法尝试截取event,由于default return false(不截取),轮到MyButton处理,return false不处理。这时候,event会交给MyButton的上级View(MyLInearLayout)的onTouchEvent进行处理,还是return false,没办法,只能由MainActivity自己处理。然后还会产生MotionEvent.ACTION_UP事件,但这个事件没有交给MyLinearLayout和MyButton处理,而是MainActivity处理,为什么?一个连续事件(如点击产生练两个事件ACTION_DOWN和ACTION_UP)处理的特点,当第一个事件(ACTION_DOWN)处理后,这个例子MyButton、MyLinearLayout不去处理,那么后续事件(ACTION_UP)就不会再交他们处理了,直接是MainActivity处理。
如果让MyLInearLayout的onInterceptTouchEvent返回true,前面说了,它用于拦截event,也就是不让event传到下一级,我们看代码:
@Overridepublic boolean onInterceptTouchEvent(MotionEvent ev) {// TODO Auto-generated method stubLog.e(TAG, "MyLinearLayout onInterceptTouchEvent return true");return true;}结果请看:
可以看到效果了吧,MyButton没有出现,因为event被MyLInearLayout拦截了,拦截之后交给它的onTouchEvent处理了,但是它的onTouchEvent不给力,return false,因此,只能由老大MainActivity处理。而MotionEvent.ACTION_UP还是由MainActivity处理,这应该知道了吧,对于连续事件中的第一个事件下级没能力处理,后续event都不会传下去。
那我把MyLinearLayout的onTouchEvent也改成返回true。看代码:
@Overridepublic boolean onTouchEvent(MotionEvent event) {// TODO Auto-generated method stubLog.e(TAG, "MyLinearLayout onTouchEvent default return true" );return true;}情况会怎样呢? 看答案:
都明白了吧,ACTION_DOWN由MyLInearLayout处理,ACTION_UP也由它来处理。
还有其他情况就不一一试了,大家有兴趣再玩一下。
===================================================先隔开一下========================================================================
下面简单说一下event的分派过程,这时候就要用到dispatchTouchEvent
Activity有这个方法,View也有,那是当然的,不然怎么分派,然后子类就可以用dispatchTouchEvent方法了。本例的分派过程如下:
event----->MainActivity------调用它的dispatchTouchEvent方法分派event------>
MyLinearLayout-------调用它的dispatchTouchEvent-----------如果不拦截(如果拦截看上面)---------->
MyButton------------调用它的dispatchTouchEvent----------->onTouchEvent处理,return false咋办?看上面
就说这么简单!!
再补充一个上面的处理event都是基于回调进行的,android还有一种监听的方法,需要设置onTouchListener。那两种方法有什么区别呢,到底会使用哪一种呢?先看一下View里的dispatchTouchEvent怎么写,学一下哈:
public boolean dispatchTouchEvent(MotionEvent event) { if (mInputEventConsistencyVerifier != null) { mInputEventConsistencyVerifier.onTouchEvent(event, 0); } if (onFilterTouchEventForSecurity(event)) { //noinspection SimplifiableIfStatement ListenerInfo li = mListenerInfo; if (li != null && li.mOnTouchListener != null && (mViewFlags & ENABLED_MASK) == ENABLED && li.mOnTouchListener.onTouch(this, event)) { return true; } if (onTouchEvent(event)) { return true; } } if (mInputEventConsistencyVerifier != null) { mInputEventConsistencyVerifier.onUnhandledEvent(event, 0); } return false; }
懒人看一下8、9、10和14行吧哈
上面的代码大体意思是:在dispatchTouchEvent方法中判断是否用了onTouchListener对象的onTouch方法处理,如果onTouch返回true,那回调方法onTouchEvent没有机会处理了,如果没有设置shionTouchListener或onTouch返回false,就由onTouchEvent处理。
内置诸如click事件的实现等等都基于onTouchEvent,假如onTouch返回true,这些事件将不会被触发。
文章烂尾了哈,希望大家喜欢。
0 0
- android 全方位理解TouchEvent
- 理解Android中的TouchEvent事件分发机制
- Android TouchEvent 事件传递机制简单理解
- android TouchEvent
- 完全理解Android TouchEvent事件分发机制(一)
- 完全理解Android TouchEvent事件分发机制(二)
- android 之 TouchEvent 示例
- Android TouchEvent 分发流程
- Android TouchEvent 分发流程
- Android TouchEvent 分发流程
- Android TouchEvent 分发流程
- Android TouchEvent 分发流程
- android touchEvent解析
- Android TouchEvent 分发流程
- Android TouchEvent 分发流程
- Android TouchEvent的传递
- Android TouchEvent 分发流程
- Android TouchEvent事件
- Oracle安装错误
- 透过maven在eclipse中直接关联源码包
- Hangover - POJ 1003 水题
- n个色子的和的概率
- 滑雪 - POJ 1088 水题
- android 全方位理解TouchEvent
- FatFs文件系统的配置问题
- winform防止窗体多次在panel内打开。
- 网狐6603服务器列表加载失败,600 秒后将重新加载, ADO 错误:0x80004005,连接失败
- 仿佛一切都是晴天
- ORACLE删除当前用户下所有的表的方法
- 自定义Windows窗体的DLL或控件的.NET框架的任何开发环境的条形码控件.NET Windows Forms Barcode
- C#的new关键字的几种用法
- 电商,昨夜谁人失眠?