Android按钮已调用setOnTouchListener,但未覆盖performClick


113

当我尝试添加onTouchListner()到按钮时,它让我

按钮已调用setOnTouchListener,但不覆盖performClick

警告。有谁知道如何修理它?

1个

btnleftclick.setOnTouchListener(new View.OnTouchListener() {
    @Override
    public boolean onTouch(View view, MotionEvent motionEvent) {
        return false;
    }
});

错误:

自定义视图已调用setOnTouchListener,但未覆盖performClick如果覆盖onTouchEvent或使用OnTouchListener的View也未实现performClick并在检测到单击时调用它,则该View可能无法正确处理可访问性操作。理想情况下,应将处理单击动作的逻辑放在View#performClick中,因为某些可访问性服务应在发生单击动作时调用performClick。


自定义视图ImageView已调用setOnTouchListener,但未覆盖performClick如果覆盖onTouchEvent或使用OnTouchListener的View也未实现performClick并在检测到单击时调用它,则该View可能无法正确处理可访问性操作。理想情况下,应将处理单击动作的逻辑放在View#performClick中,因为某些可访问性服务应在发生单击动作时调用performClick。
kas

请在这里查看我的答案:stackoverflow.com/questions/47170075/…–
lambda

Answers:


134

出现此警告是因为Android希望提醒您考虑可能正在使用您的应用的盲人或视力障碍者。建议您观看此视频,以快速了解其概况。

设置了标准的UI视图(如ButtonTextView等),以通过辅助功能服务为盲用户提供适当的反馈。当您尝试自己处理触摸事件时,您可能会忘记提供反馈。这就是警告的目的。

选项1:创建自定义视图

处理触摸事件通常是在自定义视图中完成的事情。不要太快地取消此选项。并不是那么困难。下面是一个完整的示例,该示例TextView已被覆盖以处理触摸事件:

public class CustomTextView extends AppCompatTextView {

    public CustomTextView(Context context) {
        super(context);
    }

    public CustomTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        super.onTouchEvent(event);

        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                return true;

            case MotionEvent.ACTION_UP:
                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();
        doSomething();
        return true;
    }

    private void doSomething() {
        Toast.makeText(getContext(), "did something", Toast.LENGTH_SHORT).show();
    }
}

然后,您将像这样使用它:

<com.example.myapp.CustomTextView
    android:id="@+id/textview"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:padding="20dp"
    android:text="Click me to do something"/>

有关创建自定义视图的更多详细信息,请参见我的其他答案

选项2:使警告静音

在其他时候,最好只是静默警告。例如,我不确定您要针对哪些Button事件进行触摸操作。如果你是做一个自定义按钮,并呼吁performClick()onTouchEvent像我上面做了自定义TextView,那么它将获得两次每次调用,因为Button已经调用performClick()

您可能想使警告静音的原因有两个:

  • 您与触摸事件一起执行的工作只是视觉上的。它不会影响您的应用程序的实际工作。
  • 您很冷漠,不关心让世界为盲人创造更好的地方。
  • 您太懒了,无法复制和粘贴我在上面的选项1中给您的代码。

将以下行添加到方法的开头以禁止显示警告:

@SuppressLint("ClickableViewAccessibility")

例如:

@SuppressLint("ClickableViewAccessibility")
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    Button myButton = findViewById(R.id.my_button);
    myButton.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View view, MotionEvent motionEvent) {
            return false;
        }
    });
}

1
我使用customviews是因为使用了不同的字体。像现在的Api 26一样,它引入了新功能,即xml中的字体,对于较旧的版本,使用支持库26,该库一直支持到Api16。因此,我删除了所有自定义视图。并且出现了这个愚蠢的警告,解决方案是再次创建一些我正在使用setOnTouchListener的自定义视图。哈哈哈:D太奇怪了
Shan Xeeshi

19
我不知道谷歌是否意识到他们为此浪费了多少开发人员时间。我的意思是,他们也许可以在api中处理此问题?花时间将视图分类,甚至搜索如何解决他的警告都浪费了很多时间。
TatiOverflow

如果您MotionEvent eventdoSomething()方法中需要该对象怎么办?我需要检查一下event.getY()
Mateus Gondim '18 -10-5

@MateusGondim,我不得不说我仍然没有足够的能力来执行performClick()。我最初的想法是,如果event.getY()并非真正的click事件所必需的(即,视觉UI效果),则将该逻辑移回onTouchEvent()。否则,您可以创建一个类成员变量来存储上一个操作的上移Y值。我还建议您查看一些标准视图的源代码,以便了解Android如何实现它。我需要自己研究更多。
Suragch

1
@sisisisi,当您覆盖onTouchEvent()而不是时会出现警告performClick()。这可能包括滑动或单击或尝试捕获的任何其他触摸事件。
Suragch

17

解:

  1. 创建一个扩展Button或您正在使用的任何视图的类,并覆盖performClick()

    class TouchableButton extends Button {
    
        @Override
        public boolean performClick() {
            // do what you want
            return true;
        }
    }
  2. 现在在xml和/或代码中使用此TouchableButton,警告将消失!


18
这真是太过分了。有没有办法使用现有视图?
牛奶

@牛奶不。android.widget.Button是硬编码的,因此不允许您这样做。Android开发人员团队似乎非常有意。
tom_mai78101 '18


1

自定义视图控件可能需要非标准的触摸事件行为。例如,自定义控件可以使用onTouchEvent(MotionEvent)侦听器方法来检测ACTION_DOWN和ACTION_UP事件并触发特殊的click事件。为了保持与辅助功能服务的兼容性,处理此自定义click事件的代码必须执行以下操作:

为解释的click动作生成适当的AccessibilityEvent。启用辅助功能服务以为无法使用触摸屏的用户执行自定义单击操作。为了有效地满足这些要求,您的代码应覆盖performClick()方法,该方法必须调用此方法的超级实现,然后执行click事件所需的任何操作。当检测到自定义点击动作时,该代码应随后调用您的performClick()方法。

https://developer.android.com/guide/topics/ui/accessibility/custom-views#custom-touch-events

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.