Как получить время нажатия кнопки, пока пользователь все еще держит ее в Android

Итак, я пытаюсь отобразить на кнопке время с тех пор, как пользователь начал ее нажимать, вот мой код:

btn.setOnTouchListener(new View.OnTouchListener() {

        @Override
        public boolean onTouch(View view, MotionEvent motionEvent) {

            long eventDuration;

            switch (motionEvent.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    isDown = true;
                    break;
                case MotionEvent.ACTION_UP:
                    isDown = false;
                    break;
                default:
                    break;
            }
            eventDuration = motionEvent.getEventTime() - motionEvent.getDownTime();
            btn.setText(String.valueOf(eventDuration));
            return true;

        }

    });

Код работает, за исключением того, что значение времени нажатия не обновляется, если пользователь удерживает кнопку и не двигает пальцем, потому что нет действия, такого как «MotionEvent.ACTION_HOLD». Я хочу, чтобы это значение постоянно обновлялось, даже если пользователь не двигает пальцем.

Я пытался запускать метод каждый раз, когда действие "MotionEvent.ACTION_DOWN"

while(isDown){
    eventDuration = motionEvent.getEventTime() - motionEvent.getDownTime();
                    btn.setText(String.valueOf(eventDuration));
    }

Но не сработало, цикл while не останавливается, и isDown сохранил свое последнее значение true. Может ли кто-нибудь сказать мне, как я могу заставить его работать? СПАСИБО!


person Omar Mneimneh    schedule 12.12.2016    source источник


Ответы (2)


Здесь вы можете использовать CountDownTimer, когда пользователь нажимает кнопку, запускает countDownTimer с максимальным пределом очень высокого значения и отменяет его, когда вы получаете action_up в ouTouchListener

int TICK_DURATION = 1000;
int MAX_LIMIT_IN_MILLISECONDS = Integer.MAX_VALUE;
CountDownTimer cdt = new CountDownTimer(MAX_LIMIT_IN_MILLISECONDS, TICK_DURATION) {

    public void onTick(long millisUntilFinished) {
        mTextField.setText("seconds spent: " + (MAX_LIMIT_IN_MILLISECONDS-millisUntilFinished) / 1000);
       //here you can have your logic to set text to edittext
    }

    public void onFinish() {
        // this will be called when max int value is reached!! depending upon your requirement you can restart countdownTimer here
    }

}

затем запустите это внутри, Action_down еще не запущен, иначе сбросьте его

cdt.start();

и завершите его внутри action_down

cdt.cancel();
person Ravinder Bhandari    schedule 12.12.2016
comment
Отличная идея с использованием countDownTimer. попробую спасибо! - person Omar Mneimneh; 13.12.2016

Вам нужно использовать таймер

private int timeDown;
private TimerTask timerTask = new TimerTask() {
    @Override
    public void run() {
        //update
    }
};
private Timer timer;

Затем в событии onTouch запустите таймер

btn.setOnTouchListener (новый View.OnTouchListener() {

    @Override
    public boolean onTouch(View view, MotionEvent motionEvent) {

        long eventDuration;

        switch (motionEvent.getAction()) {
            case MotionEvent.ACTION_DOWN:
                isDown = true;
                if(timer == null){
                   timer = new Timer();
                   int updateFrequency = 1000; // every second
                   timeDown = motionEvent.getDownTime();
                   timer.scheduleAtFixedRate(timerTask, 0, updateFrequency);
                }
                break;
            case MotionEvent.ACTION_UP:
                isDown = false;
                timer.cancel();
                timer = null;
                break;
            default:
                break;
        }
        return true;

    }

});
person Michael Scovell    schedule 12.12.2016