Je dois faire quelque chose lorsque l'utilisateur clique sur ImageButton
J'ai essayé de créer une classe statique qui implémente both OnClickListener
et OnTouchListener
static class ClickListenerForScrolling implements OnClickListener, OnTouchListener
qui a les méthodes suivantes:
@Override
public void onClick(View v)
et
@Override
public boolean onTouch(View arg0, MotionEvent arg1)
L'idée est de changer la source d'image de la ImageButton
lorsque l'utilisateur la touche et d'effectuer une tâche lorsque l'utilisateur clique sur ce bouton. Quelqu'un peut-il me donner un indice sur la façon de procéder?
Étant donné que les deux actions consistent en des gestes "mettre le doigt sur l'écran - lever le doigt de l'écran", vous ne pouvez pas déterminer s'il s'agit d'une action tactile ou d'une action de clic. Donc, si vous implémentez les deux écouteurs sur ce bouton d'image, un toucher/clic changera l'image ET appuiera sur le bouton. Pas sûr s'il y a un ordre déterminé de ces événements ...
Toutefois, si vous souhaitez séparer ces événements, vous devrez soit définir un geste différent de l'une des actions (comme effacer pour changer d'image), soit créer différentes zones qui gèrent les événements, par exemple, l'image ne s'adapte pas. le bouton entier et la zone libre servent de zone de clic sur le bouton.
HTH
Mettre à jour:
J'ai découvert qu'une TouchEvent
est plus générale qu'une ClickEvent
et qu'elle s'appelle donc en premier.
public abstract boolean onTouch (View v, MotionEvent event)
Ceci renvoie true, si le programme d'écoute a consommé l'événement, false sinon. Vous pouvez donc décider dans votre implémentation si l'événement doit également être géré par OnClickListener, puis renvoyez simplement false
.
La onTouchListener
est capable de gérer les deux mouvements.
Switch
entre les valeurs event.action()
pour obtenir MotionEvent
.
case MotionEvent.ACTION_DOWN
: est l'impact au premier doigt.case MotionEvent.ACTION_UP
: est le moment où le doigt s'en va.
Vous devrez définir le point d'impact sur ACTION_DOWN
.
TheImpactPoint=event.getX();
Et puis obtenir la distance avec ACTION_UP
float distance =TheImpactPoint-event.getX();
If distance = 0
alors il y a un clic, sinon ce serait plus ou moins que zéro en fonction du geste.
C'est donc la manière d'utiliser l'événement click sans événement click réel et en utilisant uniquement la variable onTouchListener
.
L'espoir sera utile.
Utilisez ce code:
public class GestureHelper implements OnTouchListener {
private final GestureDetector mGestureDetector;
public GestureHelper(Context context) {
mGestureDetector = new GestureDetector(context, new GestureListener(this));
}
public void onSwipeRight() {
};
public void onSwipeLeft() {
};
public void onSwipeTop() {
};
public void onSwipeBottom() {
};
public void onDoubleTap() {
};
public void onClick() {
};
@Override
public boolean onTouch(View v, MotionEvent event) {
return mGestureDetector.onTouchEvent(event);
}
private static final class GestureListener extends SimpleOnGestureListener {
private static final int SWIPE_THRESHOLD = 100;
private static final int SWIPE_VELOCITY_THRESHOLD = 100;
private GestureHelper mHelper;
public GestureListener(GestureHelper helper) {
mHelper = helper;
}
@Override
public boolean onDown(MotionEvent e) {
return true;
}
@Override
public boolean onSingleTapUp(MotionEvent e) {
mHelper.onClick();
return true;
}
@Override
public boolean onDoubleTap(MotionEvent e) {
mHelper.onDoubleTap();
return true;
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
boolean result = false;
try {
float diffY = e2.getY() - e1.getY();
float diffX = e2.getX() - e1.getX();
if (Math.abs(diffX) > Math.abs(diffY)) {
if (Math.abs(diffX) > SWIPE_THRESHOLD && Math.abs(velocityX) > SWIPE_VELOCITY_THRESHOLD) {
if (diffX > 0) {
mHelper.onSwipeRight();
} else {
mHelper.onSwipeLeft();
}
}
} else {
if (Math.abs(diffY) > SWIPE_THRESHOLD && Math.abs(velocityY) > SWIPE_VELOCITY_THRESHOLD) {
if (diffY > 0) {
mHelper.onSwipeBottom();
} else {
mHelper.onSwipeTop();
}
}
}
} catch (Exception ex) {
ex.printStackTrace();
}
return result;
}
}
}
Étendre cette classe et utiliser comme ça ...
view.setOnTouchListener(new SomeYourGestureHelper(context, someParameters));
Utilisez return false
au lieu de return true
Il existe de nombreuses solutions à ce problème, la meilleure pour moi consiste à éliminer totalement setOnClickListener et à l'intérieur du onTouchListener, vérifiez si l'action est ACTION_UP, puis à l'intérieur de cette vérification, si le dernier précédent est ACTION_DOWN:
case MotionEvent.ACTION_UP:
if (lastAction == MotionEvent.ACTION_DOWN) {
//code for click
.
.
lastAction = event.getAction();
}
lastAction est int et je le mets à jour à la fin de chaque action