Frage

Ich verwende die OnScroll -Methode von gestiketeetektor. Wenn die Schriftrolle beendet ist, möchte ich die Bitmap neu zeichnen, falls der Benutzer weiter scrollen möchte ... vom Rand der Bitmap, aber ich kann nicht sehen vom Bildschirm).

e2.getaction () scheint immer den Wert 2 zurückzugeben, so dass es keine Hilfe ist. E2.GetPressur scheint ziemlich konstante Werte (ca. 0,25) zurückzugeben, bis der endgültige Onscroll -Aufruf auf ca. 0,13 zu fallen scheint. Ich nehme an, ich könnte diese Druckreduzierung feststellen, aber dies wird alles andere als narrensicher sein.

Es muss einen besseren Weg geben: Kann bitte jemand helfen?

War es hilfreich?

Lösung

Hier ist, wie ich das Problem gelöst habe. Hoffe das hilft.

// declare class member variables
private GestureDetector mGestureDetector;
private OnTouchListener mGestureListener;
private boolean mIsScrolling = false;


public void initGestureDetection() {
        // Gesture detection
    mGestureDetector = new GestureDetector(new SimpleOnGestureListener() {
        @Override
        public boolean onDoubleTap(MotionEvent e) {
            handleDoubleTap(e);
            return true;
        }

        @Override
        public boolean onSingleTapConfirmed(MotionEvent e) {
            handleSingleTap(e);
            return true;
        }

        @Override
        public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
            // i'm only scrolling along the X axis
            mIsScrolling = true;                
            handleScroll(Math.round((e2.getX() - e1.getX())));
            return true;
        }

        @Override
        /**
         * Don't know why but we need to intercept this guy and return true so that the other gestures are handled.
         * https://code.google.com/p/android/issues/detail?id=8233
         */
        public boolean onDown(MotionEvent e) {
            Log.d("GestureDetector --> onDown");
            return true;
        }
    });

    mGestureListener = new View.OnTouchListener() {
        public boolean onTouch(View v, MotionEvent event) {

            if (mGestureDetector.onTouchEvent(event)) {
                return true;
            }

            if(event.getAction() == MotionEvent.ACTION_UP) {
                if(mIsScrolling ) {
                    Log.d("OnTouchListener --> onTouch ACTION_UP");
                    mIsScrolling  = false;
                    handleScrollFinished();
                };
            }

            return false;
        }
    };

    // attach the OnTouchListener to the image view
    mImageView.setOnTouchListener(mGestureListener);
}

Andere Tipps

Sie sollten sich ansehen http://developer.android.com/reference/android/widget/scroller.html. Besonders könnte dies hilfreich sein (sortiert nach Relevanz):

isFinished();
computeScrollOffset();
getFinalY(); getFinalX(); and getCurrY() getCurrX()
getDuration()

Dies bedeutet, dass Sie einen Scroller erstellen müssen.

Wenn Sie Touching verwenden möchten, können Sie auch GesteETector verwenden und Ihr eigenes Leinwand -Scrollen definieren. Das folgende Beispiel ist das Erstellen eines ScrollableImageviews. Um sie zu verwenden, müssen Sie die Messungen Ihres Bildes definieren. Sie können Ihre eigene Scroll -Reichweite definieren und nachdem Sie Ihr Bildlauf beendet haben, wird das Bild neu gezeichnet.

http://www.anddev.org/viewtopic.php?p=31487#31487

Abhängig von Ihrem Code sollten Sie ungültig berücksichtigen (int l, int t, int r, int b); für die Ungültigmachung.

SimpleOnGestureListener.onFling() 

Es scheint stattfinden, wenn eine Schriftrolle endet (dh der Benutzer lässt den Finger gehen), das benutze ich und es funktioniert großartig für mich.

Wenn ich nach ein paar Monaten darauf zurückkomme, habe ich jetzt einen anderen Tack gefolgt: Verwenden eines Handlers (wie in der Android -Snake -Probe), um alle 125 Millisekunden eine Nachricht an die App zu senden, die sie auffordert, zu überprüfen, ob eine Schriftrolle gestartet und gestartet wurde und Ob mehr als 100 Millisekunden seit dem letzten Scroll -Event verstrichen sind.

Dies scheint ziemlich gut zu funktionieren, aber wenn jemand irgendwelche Nachteile oder möglichen Verbesserungen sehen kann, sollte ich dankbar sein, von ihnen zu hören.

Der relevante Code ist in der MyView -Klasse:

public class MyView extends android.view.View {

...

private long timeCheckInterval = 125; // milliseconds
private long scrollEndInterval = 100;
public long latestScrollEventTime;
public boolean scrollInProgress = false;

public MyView(Context context) {
    super(context);
}

private timeCheckHandler mTimeCheckHandler = new timeCheckHandler();

class timeCheckHandler extends Handler{

        @Override
        public void handleMessage(Message msg) {
        long now = System.currentTimeMillis();
        if (scrollInProgress && (now>latestScrollEventTime+scrollEndInterval)) {
                    scrollInProgress = false;

// scroll ist beendet, also fügen Sie hier Code ein

// die Dodrawing () -Methode nennt

// Bitmap neu zentriert neu, wo die Scroll endete

                    [ layout or view ].invalidate();
        }
        this.sleep(timeCheckInterval);
        }

        public void sleep(long delayMillis) {
            this.removeMessages(0);
            sendMessageDelayed(obtainMessage(0), delayMillis);
            }
    }
}

@Override protected void onDraw(Canvas canvas){
        super.onDraw(canvas);

// Code zum Zeichnen von großem Puffer -Bitmap auf die Leinwand der Ansicht // positioniert, um alle laufenden Schriftrollen zu berücksichtigen

}

public void doDrawing() {

// Code zum detaillierten (und zeitaufwändigen) Zeichnen // auf Large Puffer Bitmap

// Die folgende Anweisung setzt die Zeitprüfung zurück // Die Uhr wird zuerst gestartet, wenn // die Hauptaktivität diese Methode aufruft, wenn die App startet

        mTimeCheckHandler.sleep(timeCheckInterval);
}

// Rest der MyView -Klasse

}

und in der Mygest Contexectector -Klasse

public class MyGestureDetector extends SimpleOnGestureListener {

@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
        float distanceY) {

    [MyView].scrollInProgress = true;
        long now = System.currentTimeMillis();  
    [MyView].latestScrollEventTime =now;

    [MyView].scrollX += (int) distanceX;
    [MyView].scrollY += (int) distanceY;

// Der nächste Anweisungen führt dazu

    [MyView].invalidate();

}

// Rest der MygestedEtector -Klasse

}

Ich habe das gleiche Problem untersucht. Ich habe gesehen, wie Akos CZ auf Ihre Frage antwortete. Ich habe etwas Ähnliches erstellt, aber mit meiner Version bemerkte ich, dass es nur für eine normale Schriftrolle funktioniert hat - was bedeutet, dass sie keinen Scheiner generieren. Aber wenn ein Fling generiert wurde - unabhängig davon, ob ich einen Fling verarbeitet habe oder nicht, dann erkannte er das "action_up" in "OnTouchEvent" nicht. Vielleicht war dies vielleicht nur etwas mit meiner Implementierung, aber wenn es so war, konnte ich nicht herausfinden, warum.

Nach weiteren Untersuchungen bemerkte ich, dass während eines Flinges das "Action_Up" jedes Mal in "E2" in "Onfling" übergeben wurde. Also dachte ich mir, das muss sein, warum es in diesen Fällen nicht in "OnTouchEvent" gehandhabt wurde.

Damit es für mich funktioniert, musste ich nur eine Methode anrufen, um das "action_up" in "Onfling" zu verarbeiten, und dann funktionierte sie für beide Arten des Scrollens. Im Folgenden finden Sie die genauen Schritte, die ich in meiner App implementiert habe:

-Initialisiert einen "Gesten, der" in einem Konstruktor "falsch" zu "falsch" ist.

-Ich habe es auf "wahr" in "Onscroll" gesetzt.

-Erstellen Sie eine Methode, um das Ereignis "action_up" zu verarbeiten. In diesem Ereignis setze ich "Gesturescrolling" auf False zurück und musste dann den Rest der Verarbeitung gemacht, die ich ausführen musste.

-in "OnTouchEvent", wenn ein "action_up" erkannt wurde und "Gesturescrolling" = true, dann habe ich meine Methode angerufen, um "action_up" zu handhaben.

-Und der Teil, den ich getan habe, war anders: Ich habe meine Methode auch bezeichnet, um "action_up" in "Onfling" zu handhaben.

Ich bin mir sicher, dass es für Sie zu spät ist. Es scheint jedoch, dass ich die richtige Lösung für Ihre ursprüngliche Frage gefunden habe und die Absicht nicht notwendig ist.

Wenn Sie das Scroller-/Overcroller -Objekt zum Scrollen verwenden, sollten Sie den Rückgabewert aus der folgenden Funktion überprüfen.

public boolean computeScrollOffset() 

Viel Spaß

Harvinder

Das hat für mich funktioniert.

Ich habe das Bestehende bereichert Gestortetector.ongesturelistener mit ONFINGERUP () Methode. Dieser Zuhörer macht alles als ein integriertes gestiketezerz und kann auch das Finger-Up-Ereignis anhören (es ist nicht onfling (), da dies nur dann aufgerufen wird, wenn der Finger zusammen mit einer schnellen Swipe-Aktion angehoben wird).

import android.content.Context;
import android.os.Handler;
import android.view.GestureDetector;
import android.view.MotionEvent;

public class FingerUpGestureDetector extends GestureDetector {
    FingerUpGestureDetector.OnGestureListener fListener;
    public FingerUpGestureDetector(Context context, OnGestureListener listener) {
        super(context, listener);
        fListener = listener;
    }

    public FingerUpGestureDetector(Context context, GestureDetector.OnGestureListener listener, OnGestureListener fListener) {
        super(context, listener);
        this.fListener = fListener;
    }

    public FingerUpGestureDetector(Context context, GestureDetector.OnGestureListener listener, Handler handler, OnGestureListener fListener) {
        super(context, listener, handler);
        this.fListener = fListener;
    }

    public FingerUpGestureDetector(Context context, GestureDetector.OnGestureListener listener, Handler handler, boolean unused, OnGestureListener fListener) {
        super(context, listener, handler, unused);
        this.fListener = fListener;
    }

    public interface OnGestureListener extends GestureDetector.OnGestureListener {
        boolean onFingerUp(MotionEvent e);
    }

    public static class SimpleOnGestureListener extends GestureDetector.SimpleOnGestureListener implements FingerUpGestureDetector.OnGestureListener {
        @Override
        public boolean onFingerUp(MotionEvent e) {
            return false;
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        if (super.onTouchEvent(ev)) return true;
        if (ev.getAction() == MotionEvent.ACTION_UP) {
            return fListener.onFingerUp(ev);
        }
        return false;
    }
}

Ich habe das nicht selbst gemacht, aber ich habe uns auf Ontouch () angesehen, dass Sie immer eine Sequenz 0 <2> 1 erhalten, also muss das Ende ein 1 für den Fingerlift sein.

Ich kenne Android nicht, aber wenn man sich die Dokumentation ansieht, scheint Rob zu Recht: Android action_up konstant Versuchen Sie, nach Action_Up von GetAction () zu suchen?

Bearbeiten: Was zeigt e1.getAction ()? Gibt es jemals Action_UP zurück? Die Dokumentation besagt, dass sie das erste Down -Ereignis enthält, also wird sie vielleicht auch informieren, wenn der Zeiger abgelaufen ist

Bearbeiten: Nur zwei weitere Dinge, an die ich denken kann. Zurück zurückkehren Sie zu irgendeinem Zeitpunkt falsch? Das kann Action_UP verhindern

Das einzige andere, was ich versuchen würde, ist, ein separates Ereignis zu haben, vielleicht in der Downdown, und ein Flaggen in ONSCROLL wie Isscrolling festzulegen. Wenn Action_Up für Ondown und Isscrolling eingestellt ist, können Sie alles tun, was Sie wollen, und das Isscrolling auf false zurücksetzen. Das heißt unter der Annahme, dass Ondown zusammen mit ONSCROLL gerufen wird, und GetAction wird während des Ondowns Action_UP zurückgegeben

Ich habe dies nicht versucht / benutzt, aber eine Idee für einen Ansatz:

Stop / Interrupt neu auf Leinwand bei jedem Scroll -Ereignis warten und dann auf jeder Schriftrolle neu gezogen werden.

Dies führt dazu, dass das Neuwagen nur am Ende des Bildlaufs durchgeführt wird, da nur die letzte Schriftrolle tatsächlich ununterbrochen ist, damit das Neuausgang abgeschlossen ist.

Hoffe diese Idee hilft dir :)

Auszug aus dem ONSCROLL -Ereignis von der Gesturelistener -API: Link Text

Öffentliche abstrakte boolesche Onscroll (MotionEvent E1, MotionEvent E2, Float Distance, Float Distanz) Da: API Level 1

Gibt * wahr zurück, wenn das Ereignis verzehrt wird, sonst falsch

Vielleicht ist die Aktion abgeschlossen, sobald die Veranstaltung konsumiert wurde und der Benutzer den Finger vom Bildschirm genommen hat oder diese Onscroll -Aktion zumindest beendet hat

Sie können dies dann in einer IF -Anweisung verwenden, um nach == true zu scannen und dann mit der nächsten Aktion zu beginnen.

Ich denke, das wird funktionieren, wie Sie brauchen

protected class SnappingGestureDetectorListener extends SimpleOnGestureListener{

    @Override
    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY){
        boolean result = super.onScroll(e1, e2, distanceX, distanceY);

        if(!result){
            //Do what you need to do when the scrolling stop here
        }

        return result;
    }

}

Mein Versuch, Gestendetektor zusätzliche Funktionen hinzuzufügen. Ich hoffe, es hilft jemandem, sich Zeit zu setzen, um besser zu benutzen ...

https://gist.github.com/wildorangutan/043807ddbd68978179b7cea3b53c71e8

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top