10 Stimmen

Umgang mit schnellem Tippen auf Schaltflächen

Ich habe eine Schaltfläche mit einem OnClickListener. Betrachten wir zur Veranschaulichung eine Schaltfläche, die einen modalen Dialog anzeigt:

public class SomeActivity ... {

  protected void onCreate(Bundle state) {
    super.onCreate(state);

    findViewById(R.id.ok_button).setOnClickListener(
      new View.OnClickListener() {
        public void onClick(View v) {
          // This should block input
          new AlertDialog.Builder(SomeActivity.this)
            .setCancelable(true)
            .show();
      }
    });
}

Bei normaler Verwendung erscheint der Warndialog und blockiert weitere Eingaben. Der Benutzer muss das Dialogfeld schließen, bevor er erneut auf die Schaltfläche tippen kann.

Aber manchmal wird der OnClickListener der Schaltfläche zweimal aufgerufen, bevor der Dialog erscheint. Sie können dies ganz einfach duplizieren, indem Sie sehr schnell auf die Schaltfläche tippen. Ich muss es in der Regel mehrmals versuchen, bevor es passiert, aber früher oder später werde ich mehrere onClick(...)-Aufrufe auslösen, bevor der Dialog die Eingabe blockiert.

Ich sehe dieses Verhalten in Android 2.1 auf dem Motorola Droid Telefon. Wir haben 4 Absturzberichte im Market erhalten, die darauf hinweisen, dass dieses Verhalten gelegentlich auftritt.

Je nachdem, was unsere OnClickListeners tun, verursacht dies alle Arten von Verwüstung. Wie können wir garantieren, dass blockierende Dialoge Eingaben nach dem ersten Antippen tatsächlich blockieren?

17voto

Bob Lee Punkte 1962

Romain Guy bestätigte, dass es sich tatsächlich um einen Fehler in Android handelt: "Es passiert nur, wenn es dem Benutzer gelingt, die Taste zweimal innerhalb von < 125 ms zu drücken. Ich glaube, wir haben diesen möglichen Fehler in Froyo behoben."

Wir verwenden das Muster der "Glasscheibe", um den Fehler auf älteren Betriebssystemen zu umgehen. Das heißt, wir werden den Bildschirm mit einer unsichtbaren Ansicht bedecken. Nach dem ersten Klick-Ereignis machen wir die Ansicht "sichtbar", damit sie nachfolgende Berührungsereignisse abfängt.

Es ist nicht genug, um weitere Ereignisse auf nur einer Taste zu verhindern. Sie müssen alle nachfolgenden Ereignisse für die gesamte Aktivität blockieren, bis das Dialogfeld beendet, die Aktivität wieder aufgenommen wird usw., woraufhin Sie die Glasscheibe wieder "unsichtbar" machen.

Wenn das nicht funktioniert, müssen wir einfach damit leben und unerwartete zusätzliche Ereignisse besser verkraften.

9voto

Bob Lee Punkte 1962

Danke für den Versuch, mdma, aber das ist ein Plattformproblem, kein Problem mit unserem Code. Schlimmer noch, es ist offensichtlich kein Problem, das im Benutzercode umgangen werden kann (es erfordert Details vom Touchscreen-Treiber, die nicht weitergegeben werden). Außerdem tut Ihr Code-Beispiel nicht das, was Sie glauben. show() zeigt den Dialog nicht sofort an. Es fügt eine Nachricht an das Ende der Ereigniswarteschlange hinzu, die den Dialog schließlich anzeigt. Weitere Berührungsereignisse könnten sich bereits in der Warteschlange befinden und darauf warten, nach der Rückkehr von onClick() ausgeführt zu werden.

Ich bin mir nicht sicher, warum die Leute diese Antwort wählen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X