appels onTouchEvent onClick onLongClick
-
27-10-2019 - |
Question
Dans notre application, nous traitons les événements de bouton pour enregistrer des données.
Au départ, quand j'utilise setOnLongClickListener()
et setOnClickListener()
avec le même bouton, il fonctionne très bien pour nous.
Cela signifie qu'il appellera à la fois cette base d'auditeur sur le pouvoir et LongClick du bouton. Maintenant, quand je l'ai essayé d'utiliser setOnTouchListener()
avec le même bouton avec setOnLongClickListener()
et setOnClickListener()
alors seul événement OnTouch travaille, repos et onclick événement onLongclick travail ne marche pas.
Quelqu'un peut-il me dire pourquoi cela arrive et si possible me expliquer avec un exemple.
L'utilisation i code est ..
Button btnAdd=new Button(this)
btnAdd.setOnLongClickListener(this);
btnAdd.setOnClickListener(this);
btnAdd.setOnTouchClickListener(this);
public void onClick(View v)
{
//Statements;
}
public void onLongClick(View v)
{
//Statements;
}
public boolean onTouch(View v, MotionEvent e)
{
switch (e.getAction())
{
case MotionEvent.ACTION_DOWN:
{
//store the X value when the user's finger was pressed down
m_downXValue = e.getX();
break;
}
case MotionEvent.ACTION_UP:
{
//Get the X value when the user released his/her finger
float currentX = e.getX();
//MotionEvent x=MotionEvent.obtain((long) m_downXValue, SystemClock.uptimeMillis(), MotionEvent.ACTION_UP, 1, 1, 1, 1,0, 0, 0, 0, 0);
// going forwards: pushing stuff to the left
if (m_downXValue > currentX && currentX < 0)
{
ViewFlipper vf = (ViewFlipper) findViewById(R.id.flipview);
vf.setInAnimation(AnimationUtils.loadAnimation(this, R.anim.slide_left));
vf.showNext();
}
// going backwards: pushing stuff to the right
if (m_downXValue < currentX && currentX > 100)
{
ViewFlipper vf = (ViewFlipper) findViewById(R.id.flipview);
vf.setAnimation(AnimationUtils.loadAnimation(this, R.anim.slide_right));
vf.showPrevious();
}
if (m_downXValue == currentX)
{
onClick(v);
}
break;
}
}
return true;
}
La solution
D'après la doc Gestion des événements de l'interface utilisateur ,
onLongClick () - Cette fonction renvoie un booléen pour indiquer si vous avez consommé de l'événement et il ne devrait pas aller plus loin. C'est, retourne vrai pour indiquer que vous avez traité l'événement et il devrait arrêter ici; return false si vous ne l'avez pas traité et / ou l'événement doit continuer à tous les autres écouteurs sur-clic.
Et surtout à propos OnTouch:
OnTouch () - Cette fonction renvoie une valeur booléenne pour indiquer si votre auditeur consomme cet événement. L'important est que cet événement peut avoir plusieurs actions qui se suivent. Donc, si vous revenez faux lorsque l'événement d'action vers le bas est reçu, vous indiquez que vous ne l'avez pas consommé l'événement et sont également pas intéressés par les actions ultérieures de cet événement. Ainsi, vous ne serez pas appelé pour toutes les autres actions au sein de l'événement, comme un geste du doigt, ou l'événement d'action éventuelle de haut.
En effet, selon le cas, vous devez retourner la bonne valeur.
Autres conseils
Vous devez retourner false au lieu de vrai dans la fonction OnTouch (Voir V, l'événement MotionEvent) afin que d'autres auditeurs sur le contrôle reste actif.
On dirait que vous avez un problème de référence. Essayez de cliquer ensemble, clic long et celui qui écoute tactile comme ceci:
btnAdd.setOnClickListener(new Button.OnClickListener(){
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
}
});
btnAdd.setOnLongClickListener(new Button.OnLongClickListener(){
@Override
public boolean onLongClick(View v) {
// TODO Auto-generated method stub
return false;
}
});
btnAdd.setOnTouchListener(new Button.OnTouchListener(){
@Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
return false;
}
});
Lorsque vous avez besoin des deux clics et les événements tactiles sur le même point de vue, utilisez un GestureDetector . Il peut détecter de longues presses ainsi.
Je ne suis pas sûr que ce soit ce que vous essayez d'atteindre, comme vous définissez le onTouchListener pour le bouton - et si ce que vous voulez atteindre un activité à faire glisser (par exemple glisser l'écran et le contenu de l'écran change), vous pouvez essayer de laisser votre activité étendre la classe affichée ci-dessous, puis mettre en œuvre les méthodes de next()
et previous()
avec ce que jamais les actions que vous voulez.
import android.app.Activity;
import android.os.Bundle;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.GestureDetector.SimpleOnGestureListener;
public abstract class SwipeActivity extends Activity {
private static final int SWIPE_MIN_DISTANCE = 120;
private static final int SWIPE_MAX_OFF_PATH = 250;
private static final int SWIPE_THRESHOLD_VELOCITY = 200;
private GestureDetector gestureDetector;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
gestureDetector = new GestureDetector( new SwipeDetector() );
}
private class SwipeDetector extends SimpleOnGestureListener {
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY) {
// Check movement along the Y-axis. If it exceeds SWIPE_MAX_OFF_PATH, then dismiss the swipe.
if (Math.abs(e1.getY() - e2.getY()) > SWIPE_MAX_OFF_PATH)
return false;
// Swipe from right to left.
// The swipe needs to exceed a certain distance (SWIPE_MIN_DISTANCE) and a certain velocity (SWIPE_THRESHOLD_VELOCITY).
if (e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE
&& Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
next();
return true;
}
// Swipe from left to right.
// The swipe needs to exceed a certain distance (SWIPE_MIN_DISTANCE) and a certain velocity (SWIPE_THRESHOLD_VELOCITY).
if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE
&& Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
previous();
return true;
}
return false;
}
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
//TouchEvent dispatcher.
if (gestureDetector != null) {
if (gestureDetector.onTouchEvent(ev))
//If the gestureDetector handles the event, a swipe has been executed and no more needs to be done.
return true;
}
return super.dispatchTouchEvent(ev);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
return gestureDetector.onTouchEvent(event);
}
protected abstract void previous();
protected abstract void next();
}
Voici comment i résolu une synchronisation avec OnTouch et onlongclick
L'espoir tout corps peut comprendre après avoir regardé ce code. Ce qui se passe est à chaque fois qu'une pression longue passe le touchlistener est réglé pour un écouteur sans pareil et lorsque la vue est touché à nouveau l'auditeur ne définit la touchlistener de la vue de son auditeur précédent
LinearLayout.LayoutParams longpressLP = new LinearLayout.LayoutParams(100,100);
LinearLayout longpress = new LinearLayout(this);
longpress.setBackgroundColor(Color.GREEN);
//any layout you want to add your view in
mainlayout.addView(longpress,longpressLP);
final View.OnTouchListener buttontouch=new View.OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
if(event.getAction()==MotionEvent.ACTION_DOWN)
Toast.makeText(getApplicationContext(), "Touched Down", Toast.LENGTH_SHORT).show();
else
Toast.makeText(getApplicationContext(), "Touched", Toast.LENGTH_SHORT).show();
return false;//IMPORTANT
}
};
final View.OnTouchListener buttontouchnone=new View.OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
if(event.getAction()==MotionEvent.ACTION_DOWN)//IMPORTANT
{
v.setOnTouchListener(buttontouch);//IMPORTANT
v.dispatchTouchEvent(event);//IMPORTANT
Toast.makeText(getApplicationContext(), "ChangedListener", Toast.LENGTH_SHORT).show();
}
return false;//IMPORTANT
}
};
//set listeners
longpress.setOnTouchListener(buttontouch);
longpress.setOnLongClickListener(new View.OnLongClickListener() {
public boolean onLongClick(View v) {
// TODO Auto-generated method stub
Toast.makeText(getApplicationContext(), "LongClick", Toast.LENGTH_SHORT).show();
v.setOnTouchListener(buttontouchnone);//IMPORTANT
return true;//IMPORTANT
}
});