Android 点击事件解析
来源:互联网 发布:手算工程量算法 编辑:程序博客网 时间:2024/06/05 06:18
写在前面
对Android Event事件做一个详细整理。
测试验证:
一:在Activity中只有一个View控件,给View设置了onClickListener和onTouchListener事件
test.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Log.i("TAG","onClick"); } }); test.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: Log.i("TAG","onTouch ACTION_DOWN"); break; case MotionEvent.ACTION_MOVE: Log.i("TAG","onTouch ACTION_MOVE"); break; case MotionEvent.ACTION_UP: Log.i("TAG","onTouch ACTION_UP"); break; } return false; } });
接下来对View 进行点击测试,到底是View的点击事件先执行还是onTouch先执行:
08-05 10:07:54.010 19588-19588/com.cms.testevent I/TAG: onTouch ACTION_DOWN08-05 10:07:54.070 19588-19588/com.cms.testevent I/TAG: onTouch ACTION_UP08-05 10:07:54.080 19588-19588/com.cms.testevent I/TAG: onClick
这是在点击View之后马上抬起,可以看到是先执行onTouch事件之后才到onClick事件。如果在按下View的时候手指稍微移动后在立马抬起会执行Action_Move事件,如下:
08-05 10:12:03.810 19588-19588/com.cms.testevent I/TAG: onTouch ACTION_DOWN08-05 10:12:03.860 19588-19588/com.cms.testevent I/TAG: onTouch ACTION_MOVE08-05 10:12:03.870 19588-19588/com.cms.testevent I/TAG: onTouch ACTION_UP08-05 10:12:03.870 19588-19588/com.cms.testevent I/TAG: onClick
注意到onTouch有返回值,默认返回false,那这个返回值有什么影响呢?我们进行测试:
08-05 10:19:06.290 5068-5068/com.cms.testevent I/TAG: onTouch ACTION_DOWN08-05 10:19:06.390 5068-5068/com.cms.testevent I/TAG: onTouch ACTION_MOVE08-05 10:19:06.400 5068-5068/com.cms.testevent I/TAG: onTouch ACTION_MOVE08-05 10:19:06.410 5068-5068/com.cms.testevent I/TAG: onTouch ACTION_UP
测试发现onClick不在执行了,那这又是怎么回事呢?我们从源码中去寻找答案,找到View的dispatchTouchEvent方法。
public boolean dispatchTouchEvent(MotionEvent event) { .... if (onFilterTouchEventForSecurity(event)) { if ((mViewFlags & ENABLED_MASK) == ENABLED && handleScrollBarDragging(event)) { result = true; } //noinspection SimplifiableIfStatement ListenerInfo li = mListenerInfo; if (li != null && li.mOnTouchListener != null && (mViewFlags & ENABLED_MASK) == ENABLED && li.mOnTouchListener.onTouch(this, event)) { result = true; } if (!result && onTouchEvent(event)) { result = true; } } .... return result; }
看关键代码,在第10行到14行,判断了li是否为空和li.onTouchListener是否为空,这个onTouchListener是什么呢?找到onTouchListerner发现就是前面设置的setOnTouchListener()
public void setOnTouchListener(OnTouchListener l) { getListenerInfo().mOnTouchListener = l; }
之后在判断View是否是Enable的,默认是Enable的,然后调用了onTouchListener的onTouch方法,如果返回true,那么4个条件全部满足,result为true,如果result为true那么接下来的onTouchEvent方法也就不在执行了,这也就验证了为什么onTouch返回true onClick事件就不在执行的原因。
接下来我们看下onTouchEvent的源码,只有在View是可点击的情况下才会执行事件,前面设置了setOnClickListener所以会执行点击事件,点击事件是在performClick()里面执行的。
public boolean onTouchEvent(MotionEvent event) { .... if (((viewFlags & CLICKABLE) == CLICKABLE || (viewFlags & LONG_CLICKABLE) == LONG_CLICKABLE) || (viewFlags & CONTEXT_CLICKABLE) == CONTEXT_CLICKABLE) { switch (action) { case MotionEvent.ACTION_UP: ... if (!focusTaken) { // Use a Runnable and post this rather than calling // performClick directly. This lets other visual state // of the view update before click actions start. if (mPerformClick == null) { mPerformClick = new PerformClick(); } if (!post(mPerformClick)) { performClick(); } } ... break; case MotionEvent.ACTION_DOWN: ... break; case MotionEvent.ACTION_CANCEL: ... break; case MotionEvent.ACTION_MOVE: ... break; } return true; } return false; }
点击事件在performClick()里被执行。
public boolean performClick() { final boolean result; final ListenerInfo li = mListenerInfo; if (li != null && li.mOnClickListener != null) { playSoundEffect(SoundEffectConstants.CLICK); li.mOnClickListener.onClick(this); result = true; } else { result = false; } sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED); return result; }
关于点击事件这一块先说到这里。
- Android 点击事件解析
- android 点击事件 按钮事件
- Android Widget点击事件
- Android Widget点击事件
- Android Widget点击事件
- android--点击事件写法
- android 按钮点击事件
- android 自动点击事件
- Android点击事件方法
- Android按钮点击事件
- Android按钮点击事件
- Android点击事件总结
- android点击事件分发
- android点击事件
- android点击button事件
- android点击事件分发
- android点击事件穿透
- android点击事件不灵敏
- Python中字符串、列表的基本操作
- 【LeetCode】005.Longest Palindromic Substring
- 19 Three.js实现雾化效果
- kvm安装配置_Ubuntu 14.04
- CentOS7用源码包的形式安装Nginx服务器
- Android 点击事件解析
- 并发单例模式小总结
- VS1053
- 序列的区间操作(对区间的操作,好题)
- Virtual Memory
- 来到C博客的第一天
- ZigBee OSAL流程分析
- Lintcode回文数
- mmap系统调用