onTouchEvent onClick onLongClick вызывает - PullRequest
11 голосов
/ 07 сентября 2011

В нашем приложении мы обрабатываем события в кнопке для записи данных.

Итак, изначально, когда я использую setOnLongClickListener() и setOnClickListener() вместе с одной и той же кнопкой, это прекрасно работает для нас.

Это означает, что он будет вызывать как эту базу слушателей по нажатию, так и по LongClick кнопки.Теперь, когда я попытался использовать setOnTouchListener() с одной и той же кнопкой вместе с setOnLongClickListener() и setOnClickListener(), тогда работает только событие OnTouch, не работает событие onclick и onLongclick.

Может кто-нибудь сказать мне, почему это происходити, если возможно, объясните мне пример.

Код, который я использую:

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;
}

Ответы [ 6 ]

23 голосов
/ 07 сентября 2011

Согласно документу Обработка событий пользовательского интерфейса ,

onLongClick () - возвращает логическое значение, указывающее, использовало ли вы событие, и не следует ли его переносить дальше. То есть, верните true, чтобы указать, что вы обработали событие, и оно должно остановиться здесь; вернуть false, если вы не обработали его, и / или событие должно продолжаться для любых других прослушивателей при нажатии.

И прежде всего об onTouch:

onTouch () - возвращает логическое значение, указывающее, использует ли ваш слушатель это событие. Важно то, что это событие может иметь несколько действий, которые следуют друг за другом. Таким образом, если вы возвращаете false при получении события действия вниз, вы указываете, что вы не использовали событие и также не заинтересованы в последующих действиях из этого события. Таким образом, вас не будут призывать к каким-либо другим действиям внутри события, таким как жест пальцем или событие возможного действия вверх.

Действительно, в зависимости от события вы должны вернуть правильное значение.

4 голосов
/ 07 июня 2012

Вы должны возвращать false вместо true в функции OnTouch (View v, MotionEvent), чтобы другие прослушиватели в элементе управления оставались активными.

2 голосов
/ 07 сентября 2011

Похоже, у вас есть проблема со ссылкой.Попробуйте установить щелчок, длинный щелчок и прикоснуться к слушателю так:

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;
    }
});
1 голос
/ 09 октября 2013

Если вам нужны события касания и нажатия в одном представлении, используйте GestureDetector .Он также может обнаруживать длительные нажатия.

0 голосов
/ 03 июня 2012

Вот как я решил синхронизацию с помощью ontouch и onlongclick

Надеюсь, что каждый сможет разобраться после просмотра этого кода.Что происходит, когда происходит длительное нажатие, прослушиватель сенсорных экранов настроен для прослушивателя, который не прослушивается, и при повторном прикосновении к прослушивателю, не прослушивающему прослушиватель, задает прослушиватель сенсорного экрана для предыдущего слушателя

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
        }
    });
0 голосов
/ 07 сентября 2011

Я не уверен, что это то, чего вы пытаетесь достичь, так как вы устанавливаете onTouchListener для кнопки - , но , если то, что вы хотите достичь, является проводимым действием(например, проведите пальцем по экрану, и содержимое экрана изменится) вы можете попытаться позволить своей активности расширить класс, указанный ниже, а затем реализовать методы next() и previous() с любыми действиями, которые вы захотите.

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();
}
...