MotionEvent.ACTION_UP pas appelé
Considérons le schéma suivant ci-dessous (pour un souci de meilleure compréhension de mon problème).
Comme vous pouvez le voir, j'envisage une vue de liste entouré de rembourrage. Maintenant, Si un utilisateur appuie sur un élément de liste, que l'action que j'ai à condition de lumière bleu couleur d'arrière-plan. Maintenant, Ma demande est de traiter avec les onTouch l'événement lui-même de déterminer des actions comme
- Cliquez sur
- De gauche à Droite, Glisser
- De droite à Gauche, Glisser
Voici mon code.
public boolean onTouch(View v, MotionEvent event) {
if(v == null)
{
mSwipeDetected = Action.None;
return false;
}
switch (event.getActionMasked()) {
case MotionEvent.ACTION_DOWN: {
downX = event.getRawX();
downY = event.getRawY();
mSwipeDetected = Action.Start;
//Find the child view that was touched (perform a hit test)
Rect rect = new Rect();
int childCount = listView.getChildCount();
int[] listViewCoords = new int[2];
listView.getLocationOnScreen(listViewCoords);
int x = (int) event.getRawX() - listViewCoords[0];
int y = (int) event.getRawY() - listViewCoords[1];
View child;
for (int i = 0; i < childCount; i++) {
child = listView.getChildAt(i);
child.getHitRect(rect);
if (rect.contains(x, y)) {
mDownView = child;
break;
}
}
return false; //allow other events like Click to be processed
}
case MotionEvent.ACTION_MOVE: {
upX = event.getRawX();
upY = event.getRawY();
float deltaX=0,deltaY=0;
deltaX = downX - upX;
deltaY = downY - upY;
if(deltaY < VERTICAL_MIN_DISTANCE)
{
setTranslationX(mDownView, -(deltaX));
setAlpha(mDownView, Math.max(0f, Math.min(1f, 1f - 2f * Math.abs(deltaX) / listView.getWidth())));
return false;
}
else
{
forceBringBack(v);
}
return false;
}
case MotionEvent.ACTION_UP:
{
stopX = event.getX();
float stopValueY = event.getRawY() - downY;
float stopValue = stopX - downX;
if(!mDownView.isPressed())
{
forceBringBack(mDownView);
return false;
}
boolean dismiss = false;
boolean dismissRight = false;
if(Math.abs(stopValue)<10)
{
mSwipeDetected = Action.Start;
}
else
{
mSwipeDetected = Action.None;
}
String log = "";
Log.d(log, "Here is Y" + Math.abs(stopValueY));
Log.d(log, "First Comparison of Stop Value > with/4" + (Math.abs(stopValue) > (listView.getWidth() /4)));
Log.d(log, "Second Comparison " + (Math.abs(stopValueY)<VERTICAL_MIN_DISTANCE));
Log.d(log, "Action Detected is " + mSwipeDetected + " with Stop Value " + stopValue);
if((Math.abs(stopValue) > (listView.getWidth() /4))&&(Math.abs(stopValueY)<VERTICAL_MIN_DISTANCE))
{
dismiss = true;
dismissRight = stopValue > 0;
if(stopValue>0)
{
mSwipeDetected = Action.LR;
}
else
mSwipeDetected = Action.RL;
}
Log.d(log, "Action Detected is " + mSwipeDetected + " with Stop Value after dissmiss" + stopValue);
if(dismiss)
{
if(dismissRight)
mSwipeDetected = Action.LR;
else
mSwipeDetected = Action.RL;
animate(mDownView)
.translationX(dismissRight ? listView.getWidth() : - listView.getWidth())
.alpha(0)
.setDuration(mAnimationTime)
.setListener(new AnimatorListenerAdapter() {
public void onAnimationEnd(Animator animation)
{
}
});
}
else
{
animate(mDownView)
.translationX(0)
.alpha(1)
.setDuration(mAnimationTime)
.setListener(null);
}
break;
}
}
return false;
}
Comme vous pouvez le voir, j'ai de déterminer l'action effectuée dans MotionEvent.ACTION_UP et définissez la valeur de l'Enum d'Action en conséquence. Cette logique fonctionne comme un charme si l'utilisateur n'a pas franchit la vue de la liste des limites.
Maintenant, si l'utilisateur, tout en le faisant glisser (ou plus précisément), en déplaçant son doigt le long de l'élément de la liste se déplace du bleu à l'orange, le MotionEvent.ACTION_UP ne serait pas donné à la liste, ce qui provoque mon code ne pas prendre une décision et en raison de translationX() la méthode et setAlpha(), puisque aucune Action n'est jamais déterminé dans ce cas, l'élément de liste obtient vide.
Le problème ne s'arrête pas là, puisque, je ne suis pas gonfler vue à chaque fois, même translatedX() ligne gonfle à chaque fois, conduisant à de multiples survenance d'un blanc/blanc élément de la liste.
Est-il possible de le faire même si je n'ai pas rencontre MotionEvent.ACTION_UP, je pouvais encore faire un peu de prise ?
- voir si cela résout votre question: stackoverflow.com/questions/13283827/...
Vous devez vous connecter pour publier un commentaire.
Vous devriez
return true;
danscase MotionEvent.ACTION_DOWN:
, de sorte que leMotionEvent.ACTION_UP
seront traitées.Comme expliqué sur Vue.OnTouchListener:
MotionEvent.ACTION_UP
De ne pas être appelé jusqu'à ce que leMotionEvent.ACTION_DOWN
eu lieu, une explication logique à cela est qu'il est impossible pour unACTION_UP
de se produire si unACTION_DOWN
jamais eu avant.Cette logique permet au développeur pour bloquer d'autres événements après
ACTION_DOWN
.consumed
signifie que l'événement ne sera pas transmise à l'INTERFACE couche en dessous de la consommation. Je peut tout de même être conscient de la touche, mais encore de les transmettre. Va retourner true prévenir de la baisse de couches de composants à partir de l'obtention de l'événement tactile?onTouch
. Cela rend le toucher auditeur être conscient de tous les événements et de ne pas les consommer.Également noter que dans certaines circonstances (par exemple,. l'écran de rotations), le geste peut être annulée, dans ce cas, un
MotionEvent.ACTION_UP
ne sera PAS envoyé. Au lieu d'unMotionEvent.ACTION_CANCEL
est envoyé à la place. Par conséquent, une action normale de l'instruction switch devrait ressembler à quelque chose comme ceci:Je ne pense pas que l'ajout de
return true;
de casMotionEvent.ACTION_DOWN:
serait éventuellement résoudre le problème. Il vient compliquer la situation oùreturn false
pourrait avoir fait le travail comme un charme.Quoi l'avis est:
MotionEvent.ACTION_DOWN: /*something*/return true;
va bloquer tout autre Écouteur rappels disponibles pour la vue, même onClickListenerm, tandis que correctementreturn false
dansMotionEvent.ACTION_UP:
peut aider à la MotionEvent être propagées vers la bonne destination.Référence à son code d'origine source: https://github.com/romannurik/android-swipetodismiss
return false;
àreturn true;
, il a aidé.Comme Danpe a expliqué dans sa réponse concise - j'ai dû ajouter de la ACTION_DOWN code afin d'avoir ACTION_UP reconnu.
J'ai eu l'ensemble de la onTouch(..) la méthode renvoie true quand même, donc je ne sais pas pourquoi ce n'était pas assez ... mais bien d'avoir cette solution rapide .. (merci!)