Je souhaite que la fling
détection des gestes fonctionne dans mon application Android.
Ce que j'ai est un GridLayout
qui contient 9 ImageView
s. La source se trouve ici: Romain Guys's Grid Layout .
Ce fichier que je prends est issu de l' application Photostream de Romain Guy et n'a été que légèrement adapté.
Pour la situation de clic simple, je n'ai besoin que de définir onClickListener
pour chaque ImageView
que j'ajoute être le principal activity
qui implémente View.OnClickListener
. Il semble infiniment plus compliqué de mettre en œuvre quelque chose qui reconnaît a fling
. Je suppose que c'est parce que cela peut s'étendre views
?
Si mon activité implémente,
OnGestureListener
je ne sais pas comment définir cela comme écouteur de gestes pour laGrid
ou lesImage
vues que j'ajoute.public class SelectFilterActivity extends Activity implements View.OnClickListener, OnGestureListener { ...
Si mon activité est implémentée,
OnTouchListener
je n'ai aucuneonFling
méthode pour le faireoverride
(elle a deux événements comme paramètres me permettant de déterminer si le lancer était notable).public class SelectFilterActivity extends Activity implements View.OnClickListener, OnTouchListener { ...
Si j'effectue une personnalisation
View
, commeGestureImageView
celle-ci,ImageView
je ne sais pas comment dire à l'activité qu'ilfling
s'est produit depuis la vue. Dans tous les cas, j'ai essayé et les méthodes n'étaient pas appelées lorsque j'ai touché l'écran.
J'ai vraiment besoin d'un exemple concret de ce travail à travers les vues. Quoi, quand et comment dois-je le joindre listener
? Je dois également pouvoir détecter les clics simples.
// 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;
}
}
});
Est-il possible de placer une vue transparente sur le haut de mon écran pour capturer des flings?
Si je choisis de ne pas voir inflate
mes images enfant à partir de XML, puis-je passer le GestureDetector
paramètre en tant que constructeur à une nouvelle sous-classe ImageView
que je crée?
C'est l'activité très simple pour laquelle j'essaie de faire fonctionner la fling
détection: SelectFilterActivity (Adapté de photostream) .
J'ai regardé ces sources:
Jusqu'à présent, rien n'a fonctionné pour moi et j'espérais quelques indications.
Réponses:
Merci à Code Shogun , dont j'ai adapté le code à ma situation.
Laissez votre activité se dérouler
OnClickListener
comme d'habitude:Attachez votre écouteur de gestes à toutes les vues que vous ajoutez à la disposition principale;
Observez avec émerveillement vos méthodes remplacées, à la fois
onClick(View v)
de l'activité etonFling
de l'auditeur de gestes.La danse «fling» est facultative mais encouragée.
la source
L'une des réponses ci-dessus mentionne la gestion de différentes densités de pixels mais suggère de calculer les paramètres de balayage à la main. Il convient de noter que vous pouvez réellement obtenir des valeurs échelonnées et raisonnables du système à l'aide de la
ViewConfiguration
classe:J'ai remarqué que l'utilisation de ces valeurs rend la "sensation" de fling plus cohérente entre l'application et le reste du système.
la source
swipeMinDistance = vc.getScaledPagingTouchSlop()
etswipeMaxOffPath = vc.getScaledTouchSlop()
.getScaledTouchSlop
me donne très peu de résultat de décalage, maladroitement. Par exemple, seulement 24 pixels sur un écran d'une hauteur de 540, c'est très difficile de le garder à portée avec le doigt. : SJe le fais un peu différemment, et j'ai écrit une classe de détecteurs supplémentaire qui implémente le
View.onTouchListener
onCreate
est simplement l'ajouter à la mise en page la plus basse comme ceci:où id.lowestLayout est l'id.xxx pour la vue la plus basse dans la hiérarchie de mise en page et le plus basLayout est déclaré en tant que RelativeLayout
Et puis il y a la classe réelle du détecteur de balayage d'activité:
Fonctionne vraiment bien pour moi!
la source
J'ai légèrement modifié et réparé la solution de Thomas Fankhauser
L'ensemble du système se compose de deux fichiers, SwipeInterface et ActivitySwipeDetector
SwipeInterface.java
Détecteur
il est utilisé comme ceci:
Et dans l'implémentation,
Activity
vous devez implémenter des méthodes à partir de SwipeInterface , et vous pouvez savoir sur quel affichage l'événement Swipe a été appelé.la source
v.performClick();
, qui est utilisé pour ne pas consommer l'événement sur OnClickListener, s'il est défini sur la même vueLe code du détecteur de geste de balayage ci-dessus est très utile! Vous pouvez cependant souhaiter rendre cette densité de solution agnostique en utilisant les valeurs relatives suivantes
(REL_SWIPE)
plutôt que les valeurs absolues(SWIPE_)
la source
Ma version de solution proposée par Thomas Fankhauser et Marek Sebera (ne gère pas les balayages verticaux):
SwipeInterface.java
ActivitySwipeDetector.java
la source
Cette question est un peu ancienne et en juillet 2011, Google a publié le paquet de compatibilité, révision 3) qui inclut celui
ViewPager
qui fonctionne avec Android 1.6 vers le haut. LesGestureListener
réponses publiées pour cette question ne sont pas très élégantes sur Android. Si vous recherchez le code utilisé pour basculer entre les photos dans la galerie Android ou pour changer de vue dans la nouvelle application Play Market, c'est certainementViewPager
.Voici quelques liens pour plus d'informations:
la source
Il y a une interface intégrée que vous pouvez utiliser directement pour tous les gestes:
Voici une explication pour un utilisateur de niveau basique: Il y a 2 importations soyez prudent en choisissant que les deux sont différents
la source
Il y a une proposition sur le Web (et cette page) pour utiliser ViewConfiguration. getScaledTouchSlop () pour avoir une valeur à l'échelle du périphérique pour
SWIPE_MIN_DISTANCE
.getScaledTouchSlop()
est destiné au " défilement " distance "seuil de ", pas à glisser. La distance de seuil de défilement doit être inférieure à une distance de seuil de "basculement entre les pages". Par exemple, cette fonction renvoie 12 pixels sur mon Samsung GS2, et les exemples cités dans cette page font environ 100 pixels.Avec l'API niveau 8 (Android 2.2, Froyo), vous avez
getScaledPagingTouchSlop()
, destiné au balayage de page. Sur mon appareil, il renvoie 24 (pixels). Donc, si vous êtes au niveau API <8, je pense que "2 *getScaledTouchSlop()
" devrait être le seuil de balayage "standard". Mais les utilisateurs de mon application avec de petits écrans m'ont dit que c'était trop peu ... Comme sur mon application, vous pouvez faire défiler verticalement, et changer de page horizontalement. Avec la valeur proposée, ils changent parfois de page au lieu de défiler.la source
Aussi comme amélioration mineure.
La principale raison du bloc try / catch est que e1 pourrait être nul pour le mouvement initial. en plus du try / catch, incluez un test pour null et return. semblable au suivant
la source
Il y a beaucoup d'excellentes informations ici. Malheureusement, une grande partie de ce code de traitement de fling est dispersée sur divers sites dans différents états d'achèvement, même si l'on pourrait penser que cela est essentiel pour de nombreuses applications.
J'ai pris le temps de créer un auditeur fling qui vérifie que les conditions appropriées sont remplies. J'ai ajouté un écouteur de lancement de page qui ajoute plus de vérifications pour s'assurer que les lancements atteignent le seuil des lancements de pages. Ces deux écouteurs vous permettent de limiter facilement les flings à l'axe horizontal ou vertical. Vous pouvez voir comment il est utilisé dans une vue pour faire glisser des images . Je reconnais que les gens ici ont fait la plupart des recherches --- Je viens de les rassembler dans une bibliothèque utilisable.
Ces derniers jours représentent ma première tentative de codage sur Android; attendez beaucoup plus à venir.
la source
Il s'agit d'une réponse combinée des deux réponses en haut, si quelqu'un veut une implémentation fonctionnelle.
la source
absDeltaY > minSwipeDelta
,absVelocityY > minSwipeVelocity
,absVelocityY < maxSwipeVelocity
seulement dans le cas siminSwipeDelta
! =getScaledTouchSlop
,minSwipeVelocity
! =getScaledMinimumFlingVelocity
,maxSwipeVelocity
! =getScaledMaximumFlingVelocity
, Par exemple pour vérifier que si ces soi-disant valeurs « par défaut » (je veux dire getScaledTouchSlop, getScaledMinimumFlingVelocity, getScaledMaximumFlingVelocity) sont mises à l' échelle ou modifiés en fonction de votre propre souhait.ACTION_UP
, pasACTION_MOVE
ouACTION_POINTER_UP
, c'est-à-dire uniquement comme résultat du geste pleinement réalisé). (Je n'ai pas vérifié les autres versions d'API, donc les commentaires sont appréciés).Vous pouvez utiliser la bibliothèque droidQuery pour gérer les flings, les clics, les longs clics et les événements personnalisés. L'implémentation est construite sur ma réponse précédente ci-dessous, mais droidQuery fournit une syntaxe simple et élégante :
Réponse originale
Cette réponse utilise une combinaison de composants des autres réponses ici. Il se compose de la
SwipeDetector
classe, qui possède une interface interne pour écouter les événements. Je fournis égalementRelativeLayout
pour montrer comment passer outre unView
« sonTouch
méthode pour permettre aux deux événements de glissement et d' autres événements détectés (comme les clics ou longs clics).SwipeDetector
Swipe Interceptor View
la source
SwipeInterceptorView
, donc son clic est géré en premier. Vous pouvez résoudre ce problème en implémentant votre propre mécanisme de clic en implémentantonTouchListener
, ou en guise de solution de rechange , vous pouvez écouter les clics longs au lieu de clics (voirView.setOnLongClickListener
).Je sais qu'il est trop tard pour répondre, mais je publie toujours Swipe Detection pour ListView qui explique comment utiliser Swipe Touch Listener dans ListView Item .
Réfrence: Exterminator13 (une des réponses sur cette page)
Créez un ActivitySwipeDetector.class
Appelez-le depuis votre classe d'activité comme ceci:
Et n'oubliez pas d' implémenter SwipeInterface qui vous donnera deux méthodes @override:
la source
MAX_OFF_PATH = 5 * vc.getScaledPagingTouchSlop()
c'est plus confortable pour un coup de pouce se déplaçant naturellement dans un léger arc.Les gestes sont ces mouvements subtils pour déclencher des interactions entre l'écran tactile et l'utilisateur. Il dure entre la première touche de l'écran et le moment où le dernier doigt quitte la surface.
Android nous fournit une classe appelée GestureDetector à l' aide de laquelle nous pouvons détecter des gestes courants tels que taper vers le bas et vers le haut, glisser verticalement et horizontalement (lancer), appuyer longuement et brièvement, appuyer deux fois, etc. . et attachez-leur des auditeurs.
Faites en sorte que notre classe Activity implémente les interfaces GestureDetector.OnDoubleTapListener (pour la détection de gestes à double appui) et GestureDetector.OnGestureListener et implémentez toutes les méthodes abstraites. Pour plus d'informations. vous pouvez visiter https://developer.android.com/training/gestures/detector.html . Courtoisie
Pour le test de démonstration. GestureDetectorDemo
la source
Si vous n'aimez pas créer une classe distincte ou rendre le code complexe,
vous pouvez simplement créer une variable GestureDetector dans OnTouchListener et rendre votre code plus facile
namVyuVar peut être n'importe quel nom de la vue sur laquelle vous devez définir le listeur
la source
A tous: n'oubliez pas le cas MotionEvent.ACTION_CANCEL:
il appelle à 30% des balayages sans ACTION_UP
et son égal à ACTION_UP dans ce cas
la source
J'ai intégré une classe plus générique, j'ai pris la classe de Tomas et ajouté une interface qui envoie des événements à votre activité ou fragment. il enregistrera l'écouteur sur le constructeur, alors assurez-vous d'implémenter l'interface ou une ClassCastException sera approfondie. l'interface renvoie l'un des quatre derniers int définis dans la classe et renverra la vue sur laquelle elle a été activée.
la source