Java 自定义视图。。。覆盖onTouchEvent但不覆盖performClick
我在开发的自定义Android视图中得到了这个警告(来自问题标题) 为什么我会被警告?它背后的逻辑是什么,即为什么它是好的Java 自定义视图。。。覆盖onTouchEvent但不覆盖performClick,java,android,android-view,android-custom-view,Java,Android,Android View,Android Custom View,我在开发的自定义Android视图中得到了这个警告(来自问题标题) 为什么我会被警告?它背后的逻辑是什么,即为什么它是好的 当您重写onTouchEvent时,也要练习重写performClick?此警告告诉您重写performClick @Override public boolean performClick() { // Calls the super implementation, which generates an AccessibilityEvent // a
当您重写onTouchEvent时,也要练习重写
performClick
?此警告告诉您重写performClick
@Override
public boolean performClick() {
// Calls the super implementation, which generates an AccessibilityEvent
// and calls the onClick() listener on the view, if any
super.performClick();
// Handle the action for the custom click here
return true;
}
但这不是强制性的。因为我已经创建了一个自定义knobView,它在我面临此警告的地方运行得非常好。某些辅助功能服务不会调用
onTouchEvent
,单击警告详细信息中的“更多…”链接可以解释这一点
它建议您为所需操作覆盖performClick
,或者至少在onTouchEvent
旁边覆盖它
如果您的代码更适合触摸事件,则可以使用类似于:
@Override
public boolean performClick() {
if (actionNotAlreadyExecuted) {
MotionEvent myEvent = MotionEvent.obtain(long downTime, long eventTime, int action, float x, float y, int metaState);
onTouch(myView, myEvent);
}
return true; // register it has been handled
}
有关通过代码访问触摸事件的更多信息,请访问目的是什么?
在其他一些答案中,您可以看到消除警告的方法,但首先要理解为什么系统希望您覆盖performClick()
世界上有数以百万计的盲人。也许你平时不怎么想他们,但你应该。他们也使用安卓系统。“怎么做?”你可能会问。一个重要的方法是通过应用程序。它是一个屏幕阅读器,提供音频反馈。您可以通过进入设置>辅助功能>对讲来在手机中打开它。在那里完成教程。真的很有趣。现在试着闭上眼睛使用你的应用程序。你可能会发现你的应用程序在最好的情况下非常令人讨厌,在最坏的情况下完全崩溃。这对你来说是个失败,任何视力受损的人都可以快速卸载
观看谷歌的这段精彩视频,了解如何让你的应用程序变得可访问
performClick()
让我们看一个示例自定义视图,看看重写performClick()
实际上是如何工作的。我们将制作一个简单的导弹发射应用程序。自定义视图将是启动它的按钮
如果启用了对讲功能,听起来会更好,但是动画GIF不允许音频,所以你只能自己尝试
代码
activity_main.xml
注释
- 还使用了一个
变量,该变量似乎用于过滤掉额外的润色事件,但由于对我们的应用程序没有很好的解释或严格的必要性,我将其忽略了。如果你做了一个真正的导弹发射器应用程序,我建议你多看看这个mDownTouch
- 发射导弹的主要方法(
)仅从launch飞弹()
调用。如果在performClick()
中也有它,请小心不要调用它两次。您将需要根据自定义视图的具体情况决定如何以及何时调用业务逻辑方法onTouchEvent
- 不要覆盖
,然后对其不做任何处理,只是为了消除警告。如果你想忽视世界上数以百万计的盲人,那么你可以压制这个警告。至少这样,你对自己的无情是诚实的performClick()
@SuppressLint("ClickableViewAccessibility") @Override public boolean onTouchEvent(MotionEvent event) { ... }
- (特别是该科)
launch飞弹()
)是从performClick()
)调用的。如果在ontochevent
中也有,请小心不要调用它两次。”我不知道我是否明白你的意思-你能帮我理解你所说的“如果你在onTouchEvent
中也有它,就不要叫它两次”是什么意思吗。你指的是别的什么地方?另外,您只能从内部调用performClick()
,对吗?或者,您的意思是说,在onTouchEvent()
中,由于您可以获得ACTION\u UP
和ACTION\u DOWN
,所以不要同时调用这两个属性?@Reader,系统会调用performClick()
以获取可访问性事件。在上面的代码中,我正在调用performClick()。这意味着系统和我都可能调用performClick()
,从而导致两次调用。我想我记得在子类化按钮或其他东西时遇到过这种情况。无论如何,如果你测试你的自定义视图,你应该能够知道有多少次调用了performClick()
。我喜欢这个答案,我也喜欢这个说教。感谢你在让世界变得更容易接近方面发挥了自己的作用
public class CustomView extends View {
private final static int NORMAL_COLOR = Color.BLUE;
private final static int PRESSED_COLOR = Color.RED;
public CustomView(Context context) {
super(context);
init();
}
public CustomView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init();
}
public CustomView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
setBackgroundColor(NORMAL_COLOR);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
super.onTouchEvent(event);
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
setBackgroundColor(PRESSED_COLOR);
return true;
case MotionEvent.ACTION_UP:
setBackgroundColor(NORMAL_COLOR);
// For this particular app we want the main work to happen
// on ACTION_UP rather than ACTION_DOWN. So this is where
// we will call performClick().
performClick();
return true;
}
return false;
}
// Because we call this from onTouchEvent, this code will be executed for both
// normal touch events and for when the system calls this using Accessibility
@Override
public boolean performClick() {
super.performClick();
launchMissile();
return true;
}
private void launchMissile() {
Toast.makeText(getContext(), "Missile launched", Toast.LENGTH_SHORT).show();
}
}
@SuppressLint("ClickableViewAccessibility")
@Override
public boolean onTouchEvent(MotionEvent event) { ... }