OnTouch关于performClick的Warning
OnTouch关于performClick的Warning
当你对一个控件(例如FloatingActionButton)使用setOnTouchListener() 或者是对你的自定义控件重写onTouchEvent方法时会出现这个警告,警告内容全文如下
If a View that overrides onTouchEvent or uses an OnTouchListener does not also implement performClick and call it when clicks are detected, the View may not handle accessibility actions properly. Logic handling the click actions should ideally be placed in View#performClick as some accessibility services invoke performClick when a click action should occur.
大概的意思是说
如果一个覆盖了onTouchEvent方法或者使用了OnTouchListener的控件没有引用performClick并且调用它的点击事件被拦截,控件可能不能合适的处理访问操作。逻辑上来讲处理点击操作应该更合理的被放置在View#performClick中,这样当点击事件发生时一些访问性操作可以成功请求调用performClick。
这段话各种从句太多了,费了好大劲才弄懂什么意思翻译出来。
可能意思还是不太明了,再说明一下:当你添加了一些点击操作,例如像setOnClickListener这样的,它会调用performClick才可以完成操作,但你重写了onTouch,就有可能把performClick给屏蔽了,这样这些点击操作就没办法完成了,所以就会有了这个警告。
我们来探究一下这个Warning出现的具体原因。
在View中找到onTouchEvent的源码,在ACTION_UP中可以找到这一段
if (mPerformClick == null) {
mPerformClick = new PerformClick();
}
if (!post(mPerformClick)) {
performClick();
}
继续查找PerformClick()和performClick()的源码
private final class PerformClick implements Runnable {
@Override
public void run() {
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);
notifyEnterOrExitForAutoFillIfNeeded(true);
return result;
}
可以看到在onTouchEvent的ACTION_UP过程中启用了一个新的线程来调用performClick(),而performClick()的作用时调用你在setOnClickListener时设置的onClick()方法。
一般来说这个警告都是可以忽略不用管他的,毕竟我们在自定义控件时很少会在重写了onTouchEvent后再使用setOnClickListener,这个警告主要是考虑到其他人在使用这个控件时调用这个方法,如果强迫症看着难受的话可以使用下面的方法来解决这个问题:
1 如果你是在控件内重写onTouchEvent()时遇到了这个警告,控件内直接重写performClick()方法外,还要在onTouchEvent()的ACTION_UP(DOWN其实也可以)添加performClick()的使用
@Override
public boolean performClick() {
return super.performClick();
}
if (action == MotionEvent.ACTION_UP) {
performClick();
或者:
public boolean onTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
break;
case MotionEvent.ACTION_CANCEL:
break;
case MotionEvent.ACTION_UP:
performClick();
break;
}
return true;
}
这样应该就OK了。
2 如果你在setOnTouchListener时遇到这个Warning,那么除了在控件内重写performClick()外,也需要在onTouch()中调用performClick():
button.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()){
case MotionEvent.ACTION_DOWN:
break;
case MotionEvent.ACTION_MOVE:
break;
case MotionEvent.ACTION_UP:
button.performClick();
break;
}
return false;
}
});
OnTouch关于performClick的Warning的更多相关文章
- 浅谈Android中的事件分发机制
View事件分发机制的本质就是就是MotionEvent事件的分发过程,即MotionEvent产生后是怎样在View之间传递及处理的. 首先介绍一下什么是MotionEvent.所谓MotionEv ...
- Android View的onTouchEvent和OnTouch区别
还是以自定义的TestButton为例. 我们可以通过重写onTouchEvent方法来处理诸如down move up的消息: public class TestButton extends But ...
- 【转】Android onTouch()和onTouchEvent()区别
1.onTouch()方法: onTouch方式是View的OnTouchListener接口中定义的方法. 当一个View绑定了OnTouchListener后,当有Touch事件触发时,就会调用o ...
- Android事件机制之二:onTouch详解
<Android事件机制之一:事件传递和消费>一文总结了Android中的事件传递和消费机制. 在其中对OntachEvent中的总结中,不是很具体.本文将主要对onTach进行总结. o ...
- 事件之onTouch方法的执行过程 及和 onClick执行发生冲突的解决办法
转载:http://blog.csdn.net/jiangwei0910410003/article/details/17504315#quote 博主推荐: 风萧兮兮易水寒,“天真”一去兮不复还.如 ...
- Android-事件分发(OnTouchEvent,OnTouch,OnClick)
http://blog.csdn.net/lmj623565791/article/details/38960443 http://blog.csdn.net/guolin_blog/article/ ...
- TouchEvent: dispatchTouchEvent(), onTouch() , onTouchEvent(), requestDisallowInterceptTouchEvent() 方法中的一些细节
Q: onTouchListener与onClickListener谁先执行?A: onTouchListener中的内容先执行.若其中的onTouch方法返回true,代表该事件已被onTouch消 ...
- 自定义控件(视图)2期笔记14:自定义视图之View事件分发 dispatchTouchEvent,onTouch,onTouchEvent,onClick逻辑顺序过程
1. 这里我们先从案例角度说明dispatchTouchEvent,onTouch,onTouchEvent,onClick逻辑顺序过程: (1)首先我们重写一个MyButton 继承自 Button ...
- 42、通过ontouch检测expandableListview的单击、长按、列表滚动
一.在model定义变量: public boolean isExpandableListviewScroll = false;//这个是 首先监听expandableListview的滚动: Exp ...
随机推荐
- Oracle数据库设计第三范式
一.数据库设计范式及其意义和不足 数据库的设计范式是数据库设计所需要满足的规范,数据库的规范化是优化表的结构和优化把数据组织到表中的方式,这样使数据更明确,更简洁.实践中,通常把一个数据库分成两个或多 ...
- 巨蟒python全栈开发数据库前端5:JavaScript1
1.js介绍&变量&基础数据类型 2.类型查询&运算符&if判断&for循环 3.while循环&三元运算符 4.函数 5.今日总结 1.js介绍&am ...
- 9.JavaScript简单计算器的实现
1.难点,怎么获取标签的值,注意点,获取到的值都是string类型,还要转换 var num1 = parseInt(document.getElementById("num1") ...
- js滚动显示: 滚动条置顶/底
<script> //当聊天室的内容超出页面范围时, 如何让页面刷新后 显示最下面的内容 document.getElementByIdx ( 'chatboard').scrollTop ...
- SpringMVC 之拦截器和异常处理
1. 文件上传 Spring 使用 Jakarta Commons FileUpload 技术实现了一个 MultipartResolver 实现类: CommonsMultipartResolver ...
- tagName()方法详解
1.该方法可以通过元素的标签名称来查找元素.这个方法搜索到的元素通常不止一个,所以一般建议结合使用findElements方法来使用: driver.findElement(By.xpath(&quo ...
- 【转】HTTP缓存机制
前言 Http 缓存机制作为 web 性能优化的重要手段,对于从事 Web 开发的同学们来说,应该是知识体系库中的一个基础环节,同时对于有志成为前端架构师的同学来说是必备的知识技能.但是对于很多前端同 ...
- New Moto X 2014 全版本官方解锁Bootloader图文教程
]秒后松开,手机就会进入fastboot模式. 如下图: <ignore_js_op> 接下来,手机连接电脑,打开刚刚的fastboot工具里面的命令提示符: <ignore_js_ ...
- Python HTML Resolution Demo - SGMLParser & PyQuery
1. SGMLParser: 这里定义了一个Parse类,继承SGMLParser里面的方法.使用一个变量is_h4做标记判定html文件中的h4标签,如果遇到h4标签,则将标签内的内容加入到Pars ...
- python之路 面向对象基础 XML
一.面向对象基础 1.类(Class): 用来描述具有相同的属性和方法的对象的集合.它定义了该集合中每个对象所共有的属性和方法.对象是类的实例. 类变量:类变量在整个实例化的对象中是公用的.类变量定义 ...