How to get the time a button is pressed while user still holding down in android

192 views Asked by At

So I'm trying to display on the button the time since the user started to press it, here's my code :

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;

        }

    });

The code is working except the value of the pressed time don't update if the user is holding down the button and not moving his finger because there's no Action such as "MotionEvent.ACTION_HOLD". I want that value to keep updating even if the user isn't moving his finger.

I tried to run a method each time the the Action is "MotionEvent.ACTION_DOWN"

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

But didn't work the while loop doesn't stop and isDown kept its last value true. Can anyone tell me how can I get it work? THANKS!

2

There are 2 answers

1
Ravinder Bhandari On BEST ANSWER

You can use a CountDownTimer here, when user presses the button start the countDownTimer with max limit of very high value and cancel it when you receive action_up in 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
    }

}

then start this inside Action_down is not already started otherwise reset it

cdt.start();

and finish it inside action_down

cdt.cancel();
0
Michael Scovell On

You need to use a Timer

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

Then in your onTouch event, start the Timer

btn.setOnTouchListener(new 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;

    }

});