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;
}
Était-ce utile?

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
        }
    });
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top