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; } });
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
2016-10-31 Android6.0动态权限申请步骤以及需要注意的一些坑
2016-10-31 Android 6.0 运行时权限处理
2015-10-31 Http的操作(不传递参数)
2015-10-31 Android实现异步处理 -- HTTP请求
2015-10-31 死锁 android ANR
2015-10-31 查看死锁原因 /data/anr/traces.txt
2015-10-31 Android 实现在线程中联网