Android - MotionEvent.ACTION_UP никогда не вызывается - PullRequest
0 голосов
/ 21 февраля 2019

Я хочу сделать некоторые работы, пока пользователь держит руку на виде и останавливает его, когда отпускает.Мой код ниже:

viewHolder.plus.setOnTouchListener(new View.OnTouchListener() {
        private Handler mHandler;
        @Override
        public boolean onTouch(View view, MotionEvent event) {
            switch(event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    if(mHandler==null)
                        mHandler = new Handler();
                    mHandler.postDelayed(mAction, 500);
                    return true;
                case MotionEvent.ACTION_UP:
                    Log.v("this","cancel");
                    if (mHandler != null) {
                        mHandler.removeCallbacks(mAction);
                        mHandler = null;
                        Log.v("this", "c cancel");
                    }
                    break;
            }
            return false;
        }

        Runnable mAction = new Runnable() {
            @Override public void run() {
                ChangeTedad(item.getid(), "plus");
                Log.v("this","Cc");
                mHandler.postDelayed(this, 500);
            }
        };

    });

проблема в том, что ACTION_UP никогда не вызывается и работоспособный остается работать вечно.

Как остановить работоспособность, когда пользователь ее не трогает?

Ответы [ 2 ]

0 голосов
/ 21 февраля 2019

Всякий раз, когда вы делаете одно касание в представлении, Android создает a series of touch events вместо a single touch event и буферизует эти события, затем последовательно вызывает метод onTouch на основе возвращенного значения этого метода.

ДляНапример, когда вы делаете одно прикосновение к представлению, обычная последовательность событий будет

  • ACTION_DOWN (когда вы опускаете палец)
  • опционально ACTION_MOVE (есливы двигаете пальцем, касаясь экрана)
  • ACTION_UP (когда убираете палец с экрана)

Однако, если вы вернете false из onTouchEventпереопределить в ответ на событие ACTION_XXX, вы не будете уведомлены (ваш код не будет выполнен) о любых последующих событиях.

Вернемся к вашему делу, потому что вы возвращаете false из onTouchEvent,поэтому после получения первого события (ACTION_DOWN) все последующие события (включая ACTION_UP) не будут вызваны.

Все, что вам нужно сделать, это вернуть true из метода onTouchEvent.Вот и все!

viewHolder.plus.setOnTouchListener(new View.OnTouchListener() {
    private Handler mHandler;

    @Override
    public boolean onTouch(View view, MotionEvent event) {
        switch(event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                if (mHandler == null) {
                    mHandler = new Handler();
                }
                mHandler.postDelayed(mAction, 500);
                break;
            case MotionEvent.ACTION_UP:
                Log.v("this","cancel");
                if (mHandler != null) {
                    mHandler.removeCallbacks(mAction);
                    mHandler = null;
                    Log.v("this", "c cancel");
                }
                break;
        }

        // [IMPORTANT] Return true here
        return true;
    }

    Runnable mAction = new Runnable() {
        @Override public void run() {
            ChangeTedad(item.getid(), "plus");
            Log.v("this","Cc");
            mHandler.postDelayed(this, 500);
        }
    };
}); 

Этот - действительно хороший пост, в котором рассказывается о сенсорной обработке в Android.Посмотрите на это, когда у вас будет время.

0 голосов
/ 21 февраля 2019

Вы неправильно установили флаг прерывания и возврата в сенсорном событии.

Пожалуйста, замените свой код на,

viewHolder.plus.setOnTouchListener(new View.OnTouchListener() {
        private Handler mHandler;
        @Override
        public boolean onTouch(View view, MotionEvent event) {
            switch(event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    if(mHandler==null)
                        mHandler = new Handler();
                    mHandler.postDelayed(mAction, 500);
                    break;
                case MotionEvent.ACTION_UP:
                    Log.v("this","cancel");
                    if (mHandler != null) {
                        mHandler.removeCallbacks(mAction);
                        mHandler = null;
                        Log.v("this", "c cancel");
                    }
                    break;
            }
            return true;
        }

        Runnable mAction = new Runnable() {
            @Override public void run() {
                ChangeTedad(item.getid(), "plus");
                Log.v("this","Cc");
                mHandler.postDelayed(this, 500);
            }
        };
    });

Надеюсь, это поможет вам

...