Auf der Android-Schaltfläche ist setOnTouchListener aufgerufen, überschreibt jedoch performClick nicht

111

Wenn ich versuche, onTouchListner()einen Button hinzuzufügen , bekomme ich den

Auf Button wurde setOnTouchListener aufgerufen, überschreibt jedoch performClick nicht

Warnung. Weiß jemand, wie man es behebt?

1

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

Error:

In der benutzerdefinierten Ansicht wurde setOnTouchListener aufgerufen, überschreibt jedoch nicht performClick. Wenn eine Ansicht, die onTouchEvent überschreibt oder einen OnTouchListener verwendet, performClick nicht ebenfalls implementiert und aufruft, wenn Klicks erkannt werden, verarbeitet die Ansicht die Eingabehilfen möglicherweise nicht ordnungsgemäß. Die Logik, die die Klickaktionen verarbeitet, sollte idealerweise in View # performClick platziert werden, da einige Eingabehilfedienste performClick aufrufen, wenn eine Klickaktion ausgeführt werden soll.

kas
quelle
In der benutzerdefinierten Ansicht ImageViewwurde setOnTouchListener aufgerufen, überschreibt jedoch nicht performClick. Wenn eine Ansicht, die onTouchEvent überschreibt oder einen OnTouchListener verwendet, performClick nicht ebenfalls implementiert und aufruft, wenn Klicks erkannt werden, verarbeitet die Ansicht möglicherweise die Eingabehilfen nicht ordnungsgemäß. Die Logik, die die Klickaktionen verarbeitet, sollte idealerweise in View # performClick platziert werden, da einige Eingabehilfedienste performClick aufrufen, wenn eine Klickaktion ausgeführt werden soll.
Kas
Bitte sehen Sie meine Antwort hier: stackoverflow.com/questions/47170075/…
Lambda

Antworten:

132

Diese Warnung wird angezeigt, weil Android Sie daran erinnern möchte, an blinde oder sehbehinderte Personen zu denken, die möglicherweise Ihre App verwenden. Ich schlage vor, Sie sehen sich dieses Video an, um einen schnellen Überblick darüber zu erhalten, wie das ist.

Die Standard - UI - Ansichten (wie Button, TextViewetc.) sind alle eingerichtet, um blinde Nutzer mit entsprechendem Feedback durch Zugänglichkeit Dienstleistungen. Wenn Sie versuchen, Berührungsereignisse selbst zu behandeln, besteht die Gefahr, dass Sie vergessen, dieses Feedback zu geben. Dafür ist die Warnung da.

Option 1: Erstellen Sie eine benutzerdefinierte Ansicht

Die Behandlung von Berührungsereignissen erfolgt normalerweise in einer benutzerdefinierten Ansicht. Schließen Sie diese Option nicht zu schnell ab. Es ist nicht wirklich so schwierig. Hier ist ein vollständiges Beispiel für a TextView, das für die Behandlung von Berührungsereignissen überschrieben wird:

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();
    }
}

Dann würden Sie es einfach so verwenden:

<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"/>

Weitere Informationen zum Erstellen einer benutzerdefinierten Ansicht finden Sie in meiner anderen Antwort .

Option 2: Stummschalten der Warnung

In anderen Fällen ist es möglicherweise besser, die Warnung einfach zum Schweigen zu bringen. Ich bin mir zum Beispiel nicht sicher, was Sie mit einem tun möchten, für Buttondas Sie Touch-Ereignisse benötigen. Wenn Sie eine benutzerdefinierte Taste und riefen machen sind performClick()in onTouchEventwie ich für die benutzerdefinierten oben tat TextView, dann würde es jedes Mal , zweimal aufgerufen , weil Buttonbereits Anrufe performClick().

Hier sind einige Gründe, warum Sie die Warnung möglicherweise einfach zum Schweigen bringen möchten:

  • Die Arbeit, die Sie mit Ihrem Touch-Ereignis ausführen, ist nur visuell. Dies hat keinen Einfluss auf die tatsächliche Funktionsweise Ihrer App.
  • Sie sind kaltherzig und möchten die Welt nicht zu einem besseren Ort für Blinde machen.
  • Sie sind zu faul, um den Code zu kopieren und einzufügen, den ich Ihnen in Option 1 oben gegeben habe.

Fügen Sie am Anfang der Methode die folgende Zeile ein, um die Warnung zu unterdrücken:

@SuppressLint("ClickableViewAccessibility")

Beispielsweise:

@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;
        }
    });
}
Suragch
quelle
1
Ich habe benutzerdefinierte Ansichten verwendet, weil verschiedene Schriftarten verwendet wurden. Wie jetzt in Api 26 werden neue Funktionen eingeführt, Schriftarten in XML und für ältere Versionen wird die Unterstützungsbibliothek 26 verwendet, die bis Api 16 unterstützt. Daher habe ich alle benutzerdefinierten Ansichten entfernt. Und diese dumme Warnung kommt und die Lösung besteht darin, einige der benutzerdefinierten Ansichten, für die ich setOnTouchListener verwende, erneut zu erstellen. hahaha: D So seltsam
Shan Xeeshi
19
Ich frage mich, ob Google erkennt, wie viele Entwicklerstunden sie damit verschwenden. Ich meine, könnten sie das vielleicht innerhalb der API erledigen? Zeit damit zu verbringen, Ansichten zu unterklassifizieren oder sogar zu suchen, wie seine Warnung gelöst werden kann, verschwendet viele Stunden.
TatiOverflow
Was ist, wenn Sie das MotionEvent eventObjekt in Ihrer doSomething()Methode benötigen ? Ich muss nachsehen event.getY().
Mateus Gondim
@MateusGondim, ich muss sagen, dass ich noch nicht sehr kompetent in der Umsetzung bin performClick(). Mein erster Gedanke ist, wenn das event.getY()nicht integraler Bestandteil des tatsächlichen Klickereignisses ist (dh visuelle UI-Effekte), dann verschieben Sie diese Logik zurück zu onTouchEvent(). Andernfalls können Sie eine Klassenmitgliedsvariable erstellen, um den letzten Aktionswert zu speichern Y. Ich schlage außerdem vor, dass Sie den Quellcode für einige der Standardansichten überprüfen, um zu sehen, wie Android ihn implementiert. Ich muss sie selbst mehr studieren.
Suragch
1
@sisisisi, die Warnung wird angezeigt, wenn Sie überschreiben, onTouchEvent()aber nicht performClick(). Dies kann ein Wischen oder Klicken oder ein anderes Berührungsereignis umfassen, das Sie erfassen möchten.
Suragch
17

Lösung:

  1. Erstellen Sie eine Klasse, die Button oder die von Ihnen verwendete Ansicht erweitert, und überschreiben Sie performClick ()

    class TouchableButton extends Button {
    
        @Override
        public boolean performClick() {
            // do what you want
            return true;
        }
    }
  2. Verwenden Sie jetzt diesen TouchableButton in XML und / oder Code und die Warnung wird weg sein!

Sjd
quelle
18
Das ist wirklich eklig. Gibt es keine Möglichkeit, die vorhandenen Ansichten zu verwenden?
Milch
@ Milch Nein. android.widget.Buttonist fest codiert, sodass Sie dies nicht tun können. Und es scheint sehr beabsichtigt vom Android-Entwicklerteam zu sein.
Tom_mai78101
11

Haben Sie versucht hinzuzufügen:

view.performClick()

oder Hinzufügen einer Suppresslint-Annotation:

@SuppressLint("ClickableViewAccessibility")

?

Lambda
quelle
2
Ja. Dieses waring Comeup mit Android Studio 3.0 Edition
Kas
1
Okay, ich habe eine Alternative, um diese Warnung zu beheben. Bitte sehen Sie: stackoverflow.com/questions/47170075/…
Lambda
1

Benutzerdefinierte Ansichtssteuerelemente erfordern möglicherweise ein nicht standardmäßiges Verhalten von Berührungsereignissen. Beispielsweise kann ein benutzerdefiniertes Steuerelement die Listener-Methode onTouchEvent (MotionEvent) verwenden, um die Ereignisse ACTION_DOWN und ACTION_UP zu erkennen und ein spezielles Klickereignis auszulösen. Um die Kompatibilität mit Eingabehilfediensten aufrechtzuerhalten, muss der Code, der dieses benutzerdefinierte Klickereignis behandelt, Folgendes tun:

Generieren Sie ein geeignetes AccessibilityEvent für die interpretierte Klickaktion. Aktivieren Sie Eingabehilfedienste, um die benutzerdefinierte Klickaktion für Benutzer auszuführen, die keinen Touchscreen verwenden können. Um diese Anforderungen effizient zu handhaben, sollte Ihr Code die performClick () -Methode überschreiben, die die Superimplementierung dieser Methode aufrufen und dann alle für das click-Ereignis erforderlichen Aktionen ausführen muss. Wenn die benutzerdefinierte Klickaktion erkannt wird, sollte dieser Code Ihre performClick () -Methode aufrufen.

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

vlazzle
quelle