Frage an android, long-press, timer – Android: Wie LongPress manuell in Touch-Ereignis implementieren?

2

Kurzversion: Ich möchte eine Möglichkeit zum Starten eines zeitbasierten Zählers auf einem onTouchEvent und zum Testen, ob eine bestimmte Zeitspanne verstrichen ist, bevor ich antworte, als manuelle LongTouch-Erkennung.

Erläuterung: Ich habe eine benutzerdefinierte Bildansicht, die auf zwei Fingern in den Bildschirm hinein- / hinausgleitet. Ich möchte Drag-Events hinzufügen, aber diese müssen schneller sein als ein Longpress. Ich kann das Ziehereignis verzögern, indem ich einen Zähler verwende, der einmal pro onTouchEvent aktualisiert wird und den Ziehvorgang nur bei beispielsweise 10 Zählungen auslöst. Der Zähler wird jedoch nur bei Berührungsereignissen aktualisiert, und der Finger muss sich bewegen.

Wie kann ich einen zeitbasierten Zähler erstellen, ein Feld für die Aktivitätsstufe, das 60-mal pro Sekunde oder so erhöht wird?

Deine Antwort

4   die antwort
8

Ich bin mir Ihrer Frage nicht sicher, aber es scheint, dass Sie versuchen, ein Catch Long Click-Ereignis in Ihrem onTouchListener zu implementieren, außer dass Sie eine Art Logik ausführen müssen, bevor das ACTION_UP-Ereignis eintritt? Wenn ja, ist das genau das gleiche Problem, das ich hatte. Ich habe auch versucht, mit System.nanoTime (), aber ich fand eine weniger schwierige Methode. Sie können einen Timer verwenden, Sie müssen ihn nur für das erste ACTION_DOWN-Ereignis einplanen und ihn abbrechen, wenn etwas Negatives passiert (wie ein ACTION_UP, was bedeutet, dass es kein langes Drücken, sondern nur ein Klicken ist, oder ein ACTION_MOVE mit einem Versatz über a bestimmte Schwelle). So etwas wie das folgende:

<code>layout.seyOnTouchListener(new OnTouchListener(){
    private Timer longpressTimer; //won't depend on a motion event to fire
    private final int longpressTimeDownBegin = 500; //0.5 s
    private Point previousPoint;

    switch(event.getAction()){

    case MotionEvent.ACTION_DOWN:{
        longPressTimer = new Timer();
        longpressTimer.schedule(new TimerTask(){
            //whatever happens on a longpress
        }, longpressTimeDownBegin);
        return true; //the parent was also handling long clicks
    }
    case MotionEvent.ACTION_MOVE:{
        Point currentPoint = new Point((int)event.getX(), (int)event.getY());

        if(previousPoint == null){
            previousPoint = currentPoint;
        }
        int dx = Math.abs(currentPoint.x - previousPoint.x);
        int dy = Math.abs(currentPoint.y - previousPoint.y);
        int s = (int) Math.sqrt(dx*dx + dy*dy);
        boolean isActuallyMoving = s >= minDisToMove; //we're moving

        if(isActuallyMoving){ //only restart timer over if we're actually moving (threshold needed because everyone's finger shakes a little)
            cancelLongPress();
            return false; //didn't trigger long press (will be treated as scroll)
        }
        else{ //finger shaking a little, so continue to wait for possible long press
            return true; //still waiting for potential long press
        }
    }
    default:{
        cancelLongPress();
        return false;
    }
    }
}
</code>
Wahrscheinlich kein großer Unterschied, aber als Optimierung würde ich empfehlen, die Funktion Math.sqrt () zu entfernen, da die Berechnung der Quadratwurzel einer Zahl in der Regel langsam ist. Ändern Sie einfach minDisToMove in minSquareDisToMove und weisen Sie als Schwellenwert das Quadrat der Entfernung zu. Siehe auch dasAntworten als Alternative zum Erkennen einer Langdruck. manu3d
0

Antwort: Verwenden Sie die Systemuhr (elapsedRealtime ()) und messen Sie die Millisekunden seit dem Start der Druckmaschine. Einfach, sobald Sie den Dreh raus haben.

1

Die Art und Weise, wie ich dies angehen würde, wäre, einen Booleschen Wert auf true zu setzen, wenn Action_Down auftritt. Wenn action_up auftritt, setzen Sie den Booleschen Wert auf false. Starten Sie außerdem ein postDelayed-Set mit der gewünschten Verzögerung, wenn action_down auftritt. Wenn der Boolesche Wert, den Sie zuvor auf true gesetzt haben, weiterhin true ist, tun Sie, was Sie möchten. Tut mir leid für eine so wortreiche Antwort, aber so würde ich es machen.

Ahh okay, ich verstehe, was du sagst. Wenn ich mich richtig erinnere, hat der erste Finger nach unten eine ID von 0. Ich würde das oben angegebene PostDelayed-Verfahren ausführen, aber der entscheidende Faktor wäre, ob Sie einen zweiten Finger erkennen oder nicht, oder ob der zweite PointerIndex event.getAction = ActionDown oder ActionMove . Sowas in der Art. Nur ein paar Ideen testingtester
Okay, ich verstehe, was du sagst. Ausführung verzögern und unterbrechen. Das wird aber nicht funktionieren, denke ich, weil ich kein ActionUp ausführe. Ich habe zwei Aktionen. 1) Ziehen Sie die Symbole aus dem Menü. 2) Bewegen Sie das Menü mit zwei Fingern auf dem Bildschirm. Die Verzögerung beim Ziehen soll nur zulassen, dass der zweite Finger auf den Bildschirm trifft, andernfalls wird das Ziehen gestartet, bevor der Zweifingerwurf ausgeführt werden kann. Wenn also 100 ms nach ACTION_DOWN kein zweiter Zeiger vorhanden ist, ziehen Sie ihn Tickled Pink
Ich habe festgestellt, dass ich einfach die Systemuhr verwenden und den Zeitunterschied ab dem Zeitpunkt der ersten Berührung messen kann. : D Tickled Pink
1

Schauen Sie einfach im Quellcode von Android.

Langes Drücken im GestureDetector startet eine verzögerte Meldung bei "Tastendruck". Wenn diese Meldung vor dem Drücken der Taste angezeigt wird, müssen Sie lange auf die Taste drücken.

Nur ein Link zur Quellehttp://www.devdaily.com/java/jwarehouse/android/core/java/android/view/GestureDetector.java.shtml

Danke für die Quelle. Ich schaue jetzt. Tickled Pink
Klar, ein Blick in die Quelle von GestureDetector wird jedoch zeigen, wie man das löst. Die verspätete Nachricht ist Ihre "Uhr" stefan bachert
Danke, aber ich benutze keine Gesten. Das manuelle Auswerten von Berührungsereignissen ist flexibler und bequemer für das, was ich tun möchte. Das Touch-Event-System bietet hervorragende Informationen außer Zeit. Daher ist eine einfache Uhr zum Messen von Drücken innerhalb des Berührungsereignisses erforderlich. ;) Tickled Pink

Verwandte Fragen