自定义EditText设置setOnTouchListener未重写performClick警告的解决方法
这个警告我之前也碰到过,本质是Android系统为了保障辅助功能(比如屏幕阅读器)的正常工作,对View的点击事件处理有明确的规范要求。先把警告内容和官方提示摆出来:
Custom view EditText has setOnTouchListener called on it but does not override performClick less... (Ctrl+F1)
若重写onTouchEvent或使用OnTouchListener的View未实现performClick并在检测到点击时调用它,该View可能无法正确处理辅助功能操作。点击逻辑应优先放在View#performClick中,因为部分辅助功能服务会调用perform相关方法。
简单说就是:很多辅助功能不会通过触摸事件触发点击,而是直接调用performClick()方法。如果你的View只在触摸监听里写了点击逻辑,这些辅助功能就没法正常工作,系统就会抛出这个警告。
下面给你两种靠谱的解决方式:
方法一:在触摸监听中直接调用performClick()
当你在OnTouchListener里检测到用户完成了有效点击(比如ACTION_UP事件),直接调用View的performClick()方法即可,示例代码如下:
et.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { // 这里处理你的自定义触摸逻辑 if (event.getAction() == MotionEvent.ACTION_UP) { // 必须调用这个方法,满足辅助功能的规范要求 v.performClick(); } return true; // 根据你的业务需求返回true或false } });
方法二:重写performClick()方法(更推荐,适合自定义View场景)
如果这是你自己的自定义EditText子类,建议把点击逻辑统一放在performClick()里,这样不管是用户触摸还是辅助功能调用,都能触发相同的行为。示例代码:
public class MyCustomEditText extends EditText { public MyCustomEditText(Context context) { super(context); } public MyCustomEditText(Context context, AttributeSet attrs) { super(context, attrs); } @Override public boolean performClick() { // 这里写你的核心点击逻辑 Toast.makeText(getContext(), "自定义EditText被触发点击", Toast.LENGTH_SHORT).show(); // 别忘了调用父类方法,保证系统默认的点击行为正常执行 super.performClick(); return true; } }
之后在触摸监听里触发这个方法就行:
et.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_UP) { ((MyCustomEditText)v).performClick(); } return true; } });
第二种方法更符合Android的设计规范,能让你的点击逻辑更统一,也避免了重复代码,强烈推荐用这种方式。
内容的提问来源于stack exchange,提问作者AZER

