Ich möchte, dass die fling
Gestenerkennung in meiner Android-Anwendung funktioniert.
Was ich habe, ist eine GridLayout
, die 9 ImageView
s enthält . Die Quelle finden Sie hier: Romain Guys 'Grid Layout .
Diese Datei stammt aus der Photostream-Anwendung von Romain Guy und wurde nur geringfügig angepasst.
Für die einfachen Klick Situation muss ich nur setzen die onClickListener
für jeden ImageView
ich hinzufügen die Haupt sein activity
welche Geräte View.OnClickListener
. Es scheint unendlich komplizierter, etwas zu implementieren, das a erkennt fling
. Ich nehme an, das liegt daran, dass es sich überspannen kann views
?
Wenn meine Aktivität implementiert wird
OnGestureListener
, weiß ich nicht, wie ich das als Gestenlistener für dieGrid
oder die vonImage
mir hinzugefügten Ansichten festlegen soll .public class SelectFilterActivity extends Activity implements View.OnClickListener, OnGestureListener { ...
Wenn meine Aktivität implementiert
OnTouchListener
wird, habe ich keineonFling
Methode dafüroverride
(es gibt zwei Ereignisse als Parameter, mit denen ich feststellen kann, ob der Fling bemerkenswert war).public class SelectFilterActivity extends Activity implements View.OnClickListener, OnTouchListener { ...
Wenn ich eine benutzerdefinierte machen
View
, wieGestureImageView
dass sichImageView
ich weiß nicht , wie die Aktivität zu sagen , dass einfling
aus der Sicht aufgetreten ist. Auf jeden Fall habe ich dies versucht und die Methoden wurden nicht aufgerufen, als ich den Bildschirm berührte.
Ich brauche wirklich nur ein konkretes Beispiel dafür, wie man über Ansichten hinweg arbeitet. Was, wann und wie soll ich das anhängen listener
? Ich muss auch einzelne Klicks erkennen können.
// Gesture detection
mGestureDetector = new GestureDetector(this, new GestureDetector.SimpleOnGestureListener() {
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
int dx = (int) (e2.getX() - e1.getX());
// don't accept the fling if it's too short
// as it may conflict with a button push
if (Math.abs(dx) > MAJOR_MOVE && Math.abs(velocityX) > Math.absvelocityY)) {
if (velocityX > 0) {
moveRight();
} else {
moveLeft();
}
return true;
} else {
return false;
}
}
});
Ist es möglich, eine transparente Ansicht über den oberen Bildschirmrand zu legen, um Schleudern zu erfassen?
Kann ich inflate
den GestureDetector
als Konstruktor-Parameter an eine neue Unterklasse übergeben ImageView
, die ich erstellt habe, wenn ich meine untergeordneten Bildansichten nicht aus XML auswähle ?
Dies ist die sehr einfache Aktivität, für die ich versuche, die fling
Erkennung zum Laufen zu bringen : SelectFilterActivity (Angepasst aus Fotostream) .
Ich habe mir diese Quellen angesehen:
Bisher hat nichts für mich funktioniert und ich hatte auf einige Hinweise gehofft.
Antworten:
Vielen Dank an Code Shogun , dessen Code ich an meine Situation angepasst habe.
Lassen Sie Ihre Aktivität
OnClickListener
wie gewohnt umsetzen :Fügen Sie Ihren Gesten-Listener allen Ansichten hinzu, die Sie dem Hauptlayout hinzufügen.
Beobachten Sie mit Ehrfurcht, wie Ihre überschriebenen Methoden getroffen werden, sowohl die
onClick(View v)
der Aktivität als auch dieonFling
des Gestenhörers.Der Post-Fling-Tanz ist optional, wird aber empfohlen.
quelle
Eine der obigen Antworten erwähnt die Behandlung unterschiedlicher Pixeldichten, schlägt jedoch vor, die Swipe-Parameter von Hand zu berechnen. Es ist erwähnenswert, dass Sie mithilfe der
ViewConfiguration
Klasse tatsächlich skalierte, vernünftige Werte vom System erhalten können :Ich habe festgestellt, dass die Verwendung dieser Werte dazu führt, dass das "Gefühl" des Schleuderns zwischen der Anwendung und dem Rest des Systems konsistenter ist.
quelle
swipeMinDistance = vc.getScaledPagingTouchSlop()
undswipeMaxOffPath = vc.getScaledTouchSlop()
.getScaledTouchSlop
gibt mir sehr wenig Offset-Ergebnis, umständlich. Zum Beispiel nur 24 Pixel auf einem 540 hohen Bildschirm, das ist sehr schwer, es mit dem Finger in Reichweite zu halten. : SIch mache es ein bisschen anders und habe eine zusätzliche Detektorklasse geschrieben, die das implementiert
View.onTouchListener
onCreate
Fügen Sie es einfach wie folgt zum niedrigsten Layout hinzu:Dabei ist id.lowestLayout die id.xxx für die Ansicht mit dem niedrigsten Wert in der Layouthierarchie und lowLayout als RelativeLayout deklariert
Und dann gibt es noch die eigentliche Aktivitäts-Swipe-Detektor-Klasse:
Funktioniert wirklich gut für mich!
quelle
Ich habe die Lösung von Thomas Fankhauser leicht modifiziert und repariert
Das gesamte System besteht aus zwei Dateien, SwipeInterface und ActivitySwipeDetector
SwipeInterface.java
Detektor
es wird so verwendet:
Bei der Implementierung müssen
Activity
Sie Methoden von SwipeInterface implementieren , und Sie können herausfinden, in welcher Ansicht das Swipe-Ereignis aufgerufen wurde.quelle
v.performClick();
, das verwendet wird, um Ereignis nicht auf OnClickListener zu verbrauchen, wenn auf dieselbe Ansicht gesetztDer obige Code für den Wischgestendetektor ist sehr nützlich! Möglicherweise möchten Sie diese Lösungsdichte jedoch unabhängig machen, indem Sie die folgenden relativen Werte
(REL_SWIPE)
anstelle der absoluten Werte verwenden(SWIPE_)
quelle
Meine von Thomas Fankhauser und Marek Sebera vorgeschlagene Version der Lösung (behandelt keine vertikalen Wischbewegungen):
SwipeInterface.java
ActivitySwipeDetector.java
quelle
Diese Frage ist ziemlich alt und im Juli 2011 veröffentlichte Google das Kompatibilitätspaket, Revision 3), das das enthält, das
ViewPager
mit Android 1.6 oder höher funktioniert. DieGestureListener
Antworten auf diese Frage fühlen sich auf Android nicht sehr elegant an. Wenn Sie nach dem Code suchen, der beim Wechseln zwischen Fotos in der Android-Galerie oder beim Wechseln der Ansicht in der neuen Play Market-App verwendet wird, ist dies definitiv der FallViewPager
.Hier sind einige Links für weitere Informationen:
quelle
Es gibt eine integrierte Oberfläche, die Sie direkt für alle Gesten verwenden können:
Hier ist eine Erklärung für einen Benutzer der Grundstufe: Es gibt 2 Importe. Achten Sie darauf, dass beide unterschiedlich sind
quelle
Über das Web (und diese Seite) gibt es einige Vorschläge zur Verwendung von ViewConfiguration. getScaledTouchSlop () mit einem geräteskalierten Wert für
SWIPE_MIN_DISTANCE
.getScaledTouchSlop()
ist für den Abstand " Bildlaufschwelle " vorgesehen, nicht für Wischen. Der Bildlaufschwellenabstand muss kleiner sein als ein Schwellenwertabstand zwischen Seiten. Diese Funktion gibt beispielsweise 12 Pixel auf meinem Samsung GS2 zurück, und die auf dieser Seite aufgeführten Beispiele sind ungefähr 100 Pixel.Mit API Level 8 (Android 2.2, Froyo) haben Sie es
getScaledPagingTouchSlop()
für das Wischen von Seiten vorgesehen. Auf meinem Gerät werden 24 (Pixel) zurückgegeben. Wenn Sie sich also auf API-Stufe <8 befinden, sollte "2 *getScaledTouchSlop()
" der "Standard" -Schwenkschwellenwert sein. Benutzer meiner Anwendung mit kleinen Bildschirmen sagten mir jedoch, dass es zu wenige waren ... Wie bei meiner Anwendung können Sie vertikal scrollen und die Seite horizontal wechseln. Mit dem vorgeschlagenen Wert wechseln sie manchmal die Seite, anstatt zu scrollen.quelle
Auch als kleine Verbesserung.
Der Hauptgrund für den Try / Catch-Block ist, dass e1 für die anfängliche Bewegung null sein könnte. Fügen Sie zusätzlich zu try / catch einen Test für null und return hinzu. ähnlich wie folgt
quelle
Hier gibt es viele hervorragende Informationen. Leider ist ein Großteil dieses Fling-Verarbeitungscodes an verschiedenen Standorten in verschiedenen Fertigstellungszuständen verteilt, obwohl man denken würde, dass dies für viele Anwendungen wesentlich ist.
Ich habe mir die Zeit genommen, einen Fling-Listener zu erstellen , der überprüft, ob die entsprechenden Bedingungen erfüllt sind. Ich habe einen Listener für Seitenumbrüche hinzugefügt , der weitere Überprüfungen hinzufügt, um sicherzustellen, dass Flings den Schwellenwert für Seitenumbrüche erfüllen. Mit beiden Listenern können Sie die Flings leicht auf die horizontale oder vertikale Achse beschränken. Sie können sehen, wie es in einer Ansicht zum Verschieben von Bildern verwendet wird . Ich gebe zu, dass die Leute hier den größten Teil der Forschung durchgeführt haben - ich habe es gerade in einer nutzbaren Bibliothek zusammengestellt.
Diese letzten Tage sind mein erster Versuch, auf Android zu programmieren. Erwarten Sie viel mehr .
quelle
Dies ist eine kombinierte Antwort der beiden Antworten oben, wenn jemand eine funktionierende Implementierung wünscht.
quelle
absDeltaY > minSwipeDelta
, ob ! = , ! = , ! = , Dh nur zu überprüfen, ob diese sogenannten "Standard" -Werte (ich meine getScaledTouchSlop, getScaledMinimumFlingVelocity, getScaledMaximumFlingVelocity) entsprechend Ihren Werten skaliert oder geändert werden eigener Wunsch.absVelocityY > minSwipeVelocity
absVelocityY < maxSwipeVelocity
minSwipeDelta
getScaledTouchSlop
minSwipeVelocity
getScaledMinimumFlingVelocity
maxSwipeVelocity
getScaledMaximumFlingVelocity
ACTION_UP
, nichtACTION_MOVE
oderACTION_POINTER_UP
, dh nur als ein Ergebnis der vollständig realisierten Geste). (Ich habe andere API-Versionen nicht überprüft, daher sind Kommentare willkommen.)Sie können die droidQuery- Bibliothek verwenden, um Schleudern, Klicks, lange Klicks und benutzerdefinierte Ereignisse zu verarbeiten. Die Implementierung basiert auf meiner vorherigen Antwort unten, aber droidQuery bietet eine , einfache Syntax:
Ursprüngliche Antwort
Diese Antwort verwendet eine Kombination von Komponenten aus den anderen Antworten hier. Es besteht aus der
SwipeDetector
Klasse, die eine innere Schnittstelle zum Abhören von Ereignissen hat. Ich biete auch eineRelativeLayout
an, um zu zeigen, wie man aView
's überschreibtonTouch
Verfahren beide Swipe Ereignisse und andere erkannten Ereignisse (wie Klicks oder lange Klicks) zu ermöglichen.SwipeDetector
Swipe Interceptor View
quelle
SwipeInterceptorView
, sodass der Klick zuerst behandelt wird. Sie können dies beheben, indem Sie Ihren eigenen Klickmechanismus implementierenonTouchListener
, indem Sie implementieren , oder als Umgehungslösung können Sie auf lange Klicks anstatt auf Klicks warten (sieheView.setOnLongClickListener
).Ich weiß, dass es zu spät ist, um zu antworten, aber ich poste immer noch die Swipe-Erkennung für ListView , wie man den Swipe Touch Listener in ListView Item verwendet .
Aktualisierung: Exterminator13 (eine der Antworten auf dieser Seite)
Erstellen Sie eine ActivitySwipeDetector.class
Nennen Sie es aus Ihrer Aktivitätsklasse wie folgt:
Und vergessen Sie nicht, SwipeInterface zu implementieren , mit dem Sie zwei @ override-Methoden erhalten:
quelle
MAX_OFF_PATH = 5 * vc.getScaledPagingTouchSlop()
für einen Daumenschlag, der sich natürlich in einem leichten Bogen bewegt, bequemer ist.Gesten sind diese subtilen Bewegungen, um Interaktionen zwischen dem Touchscreen und dem Benutzer auszulösen. Sie dauert zwischen der ersten Berührung des Bildschirms und dem Zeitpunkt, an dem der letzte Finger die Oberfläche verlässt.
Android bietet uns eine Klasse namens GestureDetector, mit der wir häufige Gesten wie Abwärts- und Aufwärtsklopfen, vertikales und horizontales Wischen (Schleudern), langes und kurzes Drücken, doppeltes Tippen usw. Erkennen können . und Hörer an sie anhängen.
Lassen Sie unsere Activity- Klasse GestureDetector.OnDoubleTapListener (für die Erkennung von Gesten mit doppeltem Tippen) und GestureDetector.OnGestureListener implementieren und implementieren Sie alle abstrakten Methoden. Weitere Informationen. Sie können https://developer.android.com/training/gestures/detector.html besuchen . Höflichkeit
Für den Demo-Test. GestureDetectorDemo
quelle
Wenn Sie keine separate Klasse erstellen oder Code komplex machen möchten,
möchten Sie einfach eine GestureDetector-Variable in OnTouchListener erstellen und Ihren Code einfacher gestalten
namVyuVar kann ein beliebiger Name der Ansicht sein, für die Sie den Listener festlegen müssen
quelle
An alle: Vergessen Sie nicht den Fall MotionEvent.ACTION_CANCEL:
Es werden 30% Swipes ohne ACTION_UP aufgerufen
und es ist in diesem Fall gleich ACTION_UP
quelle
Ich habe eine allgemeinere Klasse erstellt, Tomas 'Klasse genommen und eine Schnittstelle hinzugefügt, die Ereignisse an Ihre Aktivität oder Ihr Fragment sendet. Der Listener wird im Konstruktor registriert. Stellen Sie daher sicher, dass Sie die Schnittstelle implementieren. Andernfalls wird eine ClassCastException ausgeführt. Die Schnittstelle gibt eines der vier in der Klasse definierten endgültigen int zurück und gibt die Ansicht zurück, für die sie aktiviert wurde.
quelle