Search code examples
androidlistenerandroid-buttonontouchlistenermotionevent

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


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!


Solution

  • 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();