Кнопка Android встановила функціюOnTouchListener, але не перекриває функцію Click


113

Коли я намагаюся додати onTouchListner()кнопку, вона отримує мені

Кнопка setOnTouchListener закликала його, але не перекриває виконанняClick

увага. Хтось знає, як це виправити?

1

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

Помилка:

Спеціальний вигляд встановив на нього setOnTouchListener, але не переосмислить PerformClick Якщо Перегляд, який перекриває OnTouchEvent або використовує OnTouchListener, також не реалізує performClick та викликає його, коли клацання виявлено, Перегляд може не обробляти дії з доступністю. Логіка, що обробляє дії кліку, в ідеалі повинна розміщуватися у View # performClick, оскільки деякі служби доступності викликають performClick, коли має відбутися дія кліку.


Спеціальний вигляд ImageViewвстановив на нього setOnTouchListener, але не переосмислить PerformClick Якщо Перегляд, який перекриває OnTouchEvent або використовує OnTouchListener, також не реалізує performClick та викликає його, коли клацання виявлено, Перегляд може не обробляти дії з доступністю. Логіка, що обробляє дії кліку, в ідеалі повинна розміщуватися у View # performClick, оскільки деякі служби доступності викликають performClick, коли має відбутися дія кліку.
kas

Будь ласка, дивіться мою відповідь тут: stackoverflow.com/questions/47170075/…
лямбда

Відповіді:


134

Це попередження з'являється, оскільки Android хоче нагадати вам думати про сліпих або людей із вадами зору, які можуть використовувати ваш додаток. Я пропоную вам переглянути це відео для швидкого огляду того, що це таке.

Стандартні представлення інтерфейсу (наприклад Button, TextViewтощо) створені для того, щоб забезпечити незрячим користувачам відповідний зворотний зв'язок через служби доступності. Якщо ви намагаєтеся самостійно впоратися з подіями на дотик, ви загрожуєте забути надати цей відгук. Саме це і є попередженням.

Варіант 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
Я використовував власні перегляди через використання різних шрифтів. Оскільки зараз в Api 26 представлена ​​нова функція, шрифти в xml, а для старшої версії використовуйте бібліотеку підтримки 26, яка підтримує до Api 16. Тому я видалив усі власні представлення. І це дурне попередження з'являється, і рішення полягає в тому, щоб створити заново деякі ті власні представлення, для яких я використовую setOnTouchListener. hahaha: D Так дивно
Shan Xeeshi

19
Цікаво, чи Google розуміє, скільки годин розробника вони витрачають на це. Я маю на увазі, вони могли б впоратися з цим в рамках api? витрачати час на підкласифікацію поглядів або навіть шукати, як розв’язати його попереджувальні відходи багато годин.
TatiOverflow

що робити, якщо вам потрібен MotionEvent eventоб’єкт у вашому doSomething()методі? Мені потрібно перевірити event.getY().
Матеус Гондім

@MateusGondim, я мушу сказати, що я все ще не дуже компетентний у здійсненні performClick(). Моя початкова думка полягає в тому, що якщо значення event.getY()не є інтегралом до фактичної події натискання (тобто візуальних ефектів інтерфейсу користувача), тоді перенесіть цю логіку назад до onTouchEvent(). В іншому випадку ви можете створити змінну члена класу для зберігання останнього Yзначення дії . Я також пропоную вам ознайомитись з вихідним кодом для деяких стандартних представлень, щоб побачити, як Android реалізує його. Мені потрібно більше їх вивчити.
Сурагч

1
@sisisisi, попередження з’являється, коли ви переосмислюєте, onTouchEvent()але ні performClick(). Це може включати в себе пальцем чи клацанням або будь-яку іншу подію, яку ви намагаєтеся зробити.
Сурагч

17

Рішення:

  1. Створіть клас, який розширює кнопку Кнопка або будь-який інший вигляд, який ви використовуєте, і переосмислює виконанняClick ()

    class TouchableButton extends Button {
    
        @Override
        public boolean performClick() {
            // do what you want
            return true;
        }
    }
    
  2. Тепер використовуйте цю TouchableButton у xml та / або коді, і попередження не буде!


18
Це справді валово. Чи немає способу використовувати існуючі представлення даних?
Молоко

@Milk Nope. android.widget.Buttonє жорстким кодом, тому це не дозволяє вам зробити це. І, здається, це дуже навмисно від команди розробників Android.
tom_mai78101

11

Ви спробували додати:

view.performClick()

або додавання анотації до придушення:

@SuppressLint("ClickableViewAccessibility")

?


2
Так. Цей попереджувальний прийом із андроїд-студією 3.0 видання
kas

1
Гаразд, у мене є альтернатива виправити це попередження. дивіться: stackoverflow.com/questions/47170075/…
лямбда

1

Спеціальні елементи перегляду можуть вимагати нестандартної поведінки при натисканні. Наприклад, користувацьке управління може використовувати метод слухача onTouchEvent (MotionEvent) для виявлення подій ACTION_DOWN та ACTION_UP та запускати спеціальну подію клацання. Щоб підтримувати сумісність із службами доступності, код, який обробляє цю спеціальну подію кліків, повинен виконати наступне:

Створіть відповідний AccessibilityEvent для інтерпретованої дії кліку. Увімкніть служби доступності для виконання спеціальної дії кліку для користувачів, які не мають можливості використовувати сенсорний екран. Щоб ефективно керувати цими вимогами, ваш код повинен перекрити метод performClick (), який повинен викликати суперреалізацію цього методу, а потім виконати всі дії, необхідні для події клацання. Коли буде виявлена ​​спеціальна дія кліку, цей код повинен викликати ваш метод performClick ().

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.