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的更多相关文章

  1. 浅谈Android中的事件分发机制

    View事件分发机制的本质就是就是MotionEvent事件的分发过程,即MotionEvent产生后是怎样在View之间传递及处理的. 首先介绍一下什么是MotionEvent.所谓MotionEv ...

  2. Android View的onTouchEvent和OnTouch区别

    还是以自定义的TestButton为例. 我们可以通过重写onTouchEvent方法来处理诸如down move up的消息: public class TestButton extends But ...

  3. 【转】Android onTouch()和onTouchEvent()区别

    1.onTouch()方法: onTouch方式是View的OnTouchListener接口中定义的方法. 当一个View绑定了OnTouchListener后,当有Touch事件触发时,就会调用o ...

  4. Android事件机制之二:onTouch详解

    <Android事件机制之一:事件传递和消费>一文总结了Android中的事件传递和消费机制. 在其中对OntachEvent中的总结中,不是很具体.本文将主要对onTach进行总结. o ...

  5. 事件之onTouch方法的执行过程 及和 onClick执行发生冲突的解决办法

    转载:http://blog.csdn.net/jiangwei0910410003/article/details/17504315#quote 博主推荐: 风萧兮兮易水寒,“天真”一去兮不复还.如 ...

  6. Android-事件分发(OnTouchEvent,OnTouch,OnClick)

    http://blog.csdn.net/lmj623565791/article/details/38960443 http://blog.csdn.net/guolin_blog/article/ ...

  7. TouchEvent: dispatchTouchEvent(), onTouch() , onTouchEvent(), requestDisallowInterceptTouchEvent() 方法中的一些细节

    Q: onTouchListener与onClickListener谁先执行?A: onTouchListener中的内容先执行.若其中的onTouch方法返回true,代表该事件已被onTouch消 ...

  8. 自定义控件(视图)2期笔记14:自定义视图之View事件分发 dispatchTouchEvent,onTouch,onTouchEvent,onClick逻辑顺序过程

    1. 这里我们先从案例角度说明dispatchTouchEvent,onTouch,onTouchEvent,onClick逻辑顺序过程: (1)首先我们重写一个MyButton 继承自 Button ...

  9. 42、通过ontouch检测expandableListview的单击、长按、列表滚动

    一.在model定义变量: public boolean isExpandableListviewScroll = false;//这个是 首先监听expandableListview的滚动: Exp ...

随机推荐

  1. 隐藏显示终端的光标(shell echo,linux c printf)

    https://www.cnblogs.com/niocai/archive/2011/11/11/2245727.html 一.使用shell 的 echo 命令实现. echo -ne <c ...

  2. c++相关知识

    0.C语言基础知识及系统相关:http://c.biancheng.net/cpp/u/jiaocheng/ 1.C++ include观点与机制:http://developer.51cto.com ...

  3. django 表单系统 之 forms.ModelForm

    继承forms.ModelForm类实现django的表单系统 有时,我们在前端定义的<form>表单和后端定义的model结构基本上是一样的,那么我们可以直接在后端定义model后,定义 ...

  4. SQL Server 加前导0

    declare @a int declare @b int set @a = 1 --需要显示的数字 set @b = 3 --显示位数 select right(cast(power(10,@b) ...

  5. xcode中全文查询某个中文字

    查询所有中文 [^"]*[\u4E00-\u9FA5]+[^"\n]*? 查询某个中文字“中”字 [^"]*[\u4e2d]+[^"\n]*? 中文字转成uni ...

  6. corethink功能模块探索开发(十七)opencmf.php 配置文件

    图样: opencmf.php存在于每个模块的根目录,是模块配置文件. 能进行持久化配置参数保存,一开始我以为是写文件或者做缓存,后来在数据库中发现admin_module表,存储了每个模块的配置参数 ...

  7. jdk1.7 ArrayList源码浅析

    参考:http://www.cnblogs.com/xrq730/p/4989451.html(借鉴的有点多,哈哈) 首先介绍ArrayList的特性: 1.允许元素为空.允许重复元素 2.有序,即插 ...

  8. 访问url

    你可以通过 args 属性来访问 URL 中提交的参数 ( ?key=value ): searchword = request.args.get('q', '') from flask import ...

  9. Python(面向对象编程—1)

    class tst: l=[] x=1 a=tst() b=tst() a.l.append('a') b.l.append('b') a.x='a' b.x='b' print(a.l,a.x) # ...

  10. Ecstore 会员中心 菜单添加一项

    1.会员中心 添加菜单 ecstore_合并支付总结_会员中心添加菜单_20160113 class : b2c_ctl_site_member (图 1)     第一步: (图1)         ...