Ich habe ein Problem mit meiner App: Wenn der Benutzer mehrmals schnell auf die Schaltfläche klickt, werden mehrere Ereignisse generiert, bevor selbst mein Dialogfeld mit der Schaltfläche verschwindet
Ich kenne eine Lösung, indem ich eine boolesche Variable als Flag setze, wenn auf eine Schaltfläche geklickt wird, damit zukünftige Klicks verhindert werden können, bis der Dialog geschlossen wird. Ich habe jedoch viele Knöpfe und dies jedes Mal für jeden Knopf tun zu müssen, scheint ein Overkill zu sein. Gibt es in Android keine andere Möglichkeit (oder vielleicht eine intelligentere Lösung), nur Ereignisaktionen zuzulassen, die pro Schaltflächenklick generiert werden?
Was noch schlimmer ist, ist, dass mehrere schnelle Klicks mehrere Ereignisaktionen zu generieren scheinen, bevor die erste Aktion ausgeführt wird. Wenn ich also die Schaltfläche in der ersten Klickbehandlungsmethode deaktivieren möchte, sind bereits Ereignisaktionen in der Warteschlange vorhanden, die darauf warten, behandelt zu werden!
Bitte helfen Sie Danke
Antworten:
Hier ist ein "entprellter" onClick-Listener, den ich kürzlich geschrieben habe. Sie geben an, wie viele Millisekunden zwischen den Klicks mindestens zulässig sind. Implementieren Sie Ihre Logik in
onDebouncedClick
stattonClick
quelle
Mit RxBinding ist dies problemlos möglich. Hier ist ein Beispiel:
Fügen Sie die folgende Zeile hinzu
build.gradle
, um die RxBinding-Abhängigkeit hinzuzufügen:quelle
Hier ist meine Version der akzeptierten Antwort. Es ist sehr ähnlich, versucht aber nicht, Ansichten in einer Karte zu speichern, was ich nicht für eine so gute Idee halte. Außerdem wird eine Wrap-Methode hinzugefügt, die in vielen Situationen nützlich sein kann.
quelle
myButton.setOnClickListener(OnSingleClickListener.wrap(myOnClickListener))
Wir können es ohne Bibliothek tun. Erstellen Sie einfach eine einzige Erweiterungsfunktion:
Zeigen Sie onClick mit dem folgenden Code an:
quelle
Sie können dieses Projekt verwenden: https://github.com/fengdai/clickguard , um dieses Problem mit einer einzigen Anweisung zu beheben:
UPDATE: Diese Bibliothek wird nicht mehr empfohlen. Ich bevorzuge Nikitas Lösung. Verwenden Sie stattdessen RxBinding.
quelle
ListView
Hier ist ein einfaches Beispiel:
quelle
Nur ein kurzes Update der GreyBeardedGeek-Lösung. Ändern Sie die if-Klausel und fügen Sie die Math.abs-Funktion hinzu. Stellen Sie es so ein:
Der Benutzer kann die Uhrzeit auf einem Android-Gerät ändern und in die Vergangenheit verschieben, ohne dass dies zu Fehlern führen kann.
PS: Ich habe nicht genug Punkte, um Ihre Lösung zu kommentieren, also habe ich einfach eine andere Antwort gegeben.
quelle
Hier ist etwas, das mit jedem Ereignis funktioniert, nicht nur mit Klicks. Es wird auch das letzte Ereignis liefern, selbst wenn es Teil einer Reihe von schnellen Ereignissen ist (wie z . B. RX-Debounce ).
1) Erstellen Sie den Debouncer in einem Feld des Listeners, jedoch außerhalb der Rückruffunktion, konfiguriert mit Timeout und dem Rückruf fn, den Sie drosseln möchten.
2) Rufen Sie die Spam-Methode Ihres Debouncers in der Rückruffunktion des Listeners auf.
quelle
Ähnliche Lösung mit RxJava
quelle
Diese Antwort wird also von der ButterKnife-Bibliothek bereitgestellt.
Diese Methode verarbeitet Klicks erst, nachdem der vorherige Klick ausgeführt wurde. Beachten Sie, dass mehrere Klicks in einem Frame vermieden werden.
quelle
Ein
Handler
basierter Throttler von Signal App .Anwendungsbeispiel:
Beispielverwendung in einem
OnClickListener
:Beispiel Kt-Verwendung:
Oder mit einer Erweiterung:
Dann Beispielverwendung:
quelle
Ich benutze diese Klasse zusammen mit der Datenbindung. Funktioniert super.
Und mein Layout sieht so aus
quelle
Eine wichtigere Methode zur Behandlung dieses Szenarios ist die Verwendung des Throttling-Operators (Throttle First) mit RxJava2. Schritte, um dies in Kotlin zu erreichen:
1). Abhängigkeiten: - Fügen Sie die rxjava2-Abhängigkeit in der Datei auf der Ebene der build.gradle-App-Ebene hinzu.
2). Erstellen Sie eine abstrakte Klasse, die View.OnClickListener implementiert und den ersten Throttle-Operator enthält, um die OnClick () -Methode der Ansicht zu verarbeiten. Code-Snippet ist wie folgt:
3). Implementieren Sie diese SingleClickListener-Klasse beim Klicken auf Ansicht in Aktivität. Dies kann erreicht werden als:
Durch die Implementierung dieser obigen Schritte in die App können Sie einfach die mehrfachen Klicks auf eine Ansicht bis zu 600 ms vermeiden. Viel Spaß beim Codieren!
quelle
Dies wird so gelöst
quelle
Hier ist eine ziemlich einfache Lösung, die mit Lambdas verwendet werden kann:
Hier ist das Copy / Paste-Ready-Snippet:
Genießen!
quelle
Basierend auf der Antwort von @GreyBeardedGeek ,
debounceClick_last_Timestamp
umids.xml
den vorherigen Klick-Zeitstempel zu markieren.Fügen Sie diesen Codeblock hinzu
BaseActivity
Verwendung:
Mit Lambda
quelle
Geben Sie hier ein kleines Beispiel
quelle
Meine Lösung muss aufgerufen werden,
removeall
wenn wir das Fragment und die Aktivität verlassen (zerstören):quelle
Ich würde sagen, der einfachste Weg ist die Verwendung einer "Lade" -Bibliothek wie KProgressHUD.
https://github.com/Kaopiz/KProgressHUD
Das erste, was bei der onClick-Methode getan wird, ist, die Ladeanimation aufzurufen, die sofort die gesamte Benutzeroberfläche blockiert, bis der Entwickler beschließt, sie freizugeben.
Sie hätten dies also für die onClick-Aktion (dies verwendet Butterknife, funktioniert aber offensichtlich mit jeder Art von Ansatz):
Vergessen Sie auch nicht, die Schaltfläche nach dem Klicken zu deaktivieren.
Dann:
Und wenn Sie möchten, können Sie die stopHUDSpinner-Methode in der doAction () -Methode verwenden:
Aktivieren Sie die Schaltfläche gemäß Ihrer App-Logik erneut: button.setEnabled (true);
quelle