Search code examples
javaandroidandroid-fragmentstimercountdowntimer

How can I set a variable duration timer in (mm:ss) format using editText?


I'm a complete novice when it comes to java. I study learning and human behavior for a living and have need for an app with two types of timers.

These timers will live in a fragment.

The first type of timer will take user input (an interval - minutes, seconds, or both) and count down. Upon hitting zero, this timer would reset to the original input value and start again. The user would also have the option to hit a "reset" button to start the timer from the original input value (e.g. if number entered = 5, 5-4-3-2-1-0-5-4-3-reset-5-4-3-2-1-0)

The second type of timer will again take user input. When the timer starts, it will count down from a number between two input values. The user would have the option to hit a "reset" button to start the timer from a new number between 0 and the number entered (e.g. if number range entered = 3 and 7, 4-3-2-1-0-6-5-4-reset-1-0-7-6-reset-2-1-0.)

Right now I have a timer that counts down in minutes from a fixed interval, but the user can only input minutes, not seconds (e.g. if "1" is pressed, 01:00 is set and if "130" is pressed, 01:00 is still set. I'd like to have the option for the user to set 01:30 or 00:30.)

Any help would be greatly appreciated!

In addition to spending the last 6 hours watching YouTube videos, reading the forums, and looking through the Android Developer site,I've tried adjusting the divisor for int minutes = (int) (TimeLeftInMillis) and int seconds "", I've tried changing the multiplied value in long millisInput = Long.parseLong(input) * value. I've also tried whining and cursing.

mButtonSet.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(android.view.View view) {
                String input = mEditTextInput.getText().toString();
                if (input.length() == 0) {
                    Toast.makeText(getActivity(), "Fill it in, loser", Toast.LENGTH_SHORT).show();
                    return;
                }

                long millisInput = Long.parseLong(input) * 60000;
                if (millisInput == 0) {
                    Toast.makeText(getActivity(), "Please enter a positive number", Toast.LENGTH_SHORT).show();
                    return;
                }

private void startTimer() {
        mCountDownTimer = new CountDownTimer(mTimeLeftInMillis, 100) {
            @Override
            public void onTick(long millisUntilFinished) {
                mTimeLeftInMillis = millisUntilFinished;
                updateCountDownText();
            }

private void updateCountDownText() {
        int minutes = (int) (mTimeLeftInMillis / 1000)/60;
        int seconds = (int) (mTimeLeftInMillis / 1000)% 60;

        String timeLeftFormatted = String.format(Locale.getDefault(),

        timeLeftFormatted = String.format(Locale.getDefault(), "%02d:%02d", minutes, seconds));
        mTextViewCountdown.setText(timeLeftFormatted);

Solution

  • In general, Edittexts can't take multiple inputs, so we need an workaround. Option 1: Choose to constrain the user to input in the format mm:ss, and parse it as follows:

     String input[] = mEditTextInput.getText().toString().split(":");
    //input[0] is minutes and input[1] is seconds
    

    Option 2: Use two Edittexts, one beside the other and a Textview between them holding the string ":", and get the input as follows:

     String input1 = mEditTextInput.getText().toString();
     String input2 = mEditTextInput2.getText().toString();
    

    Option 3: Use a simple Textview, and detect the user's keypresses to fill in the value. You will also need to variable to detect the number of valid presses so far (incremented on entering a number, decremented on pressing the x key). Like say, the initial value in Textview will be 00:00, and on detecting keypress "1", you can use the following code to display it:

    String str=getKey();
    String str2=mTextView.getText().toString();
    if(numKey==0)//numkey is the number of valid presses
    {
        String toSet="0"+str+":00";
        mTextView.setText(toSet);
    }
    else if(numKey==1)
    {
        String toSet=str+str2.substring(1);
        mTextView.setText(toSet);
    }
    //and so on...
    

    The getKey() function can be implemented as follows:

    @Override 
    public boolean onKeyDown(int keyCode, KeyEvent event) {
    
        switch (keyCode) {
            case KeyEvent.KEYCODE_A:
            {
                //your Action code
                return true;
            }
        }
        return super.onKeyDown(keyCode, event);
    }
    

    In fact, you can remove the line

    String str=getKey();
    

    and in place of the action, you can simply call the function (say formatTextView) and pass the key as a parameter to it, which will take care of setting the textView. Finally, get your value back as required by using mTextView.getText().toString();

    Note: Option 3 won't work if your fragment has any other Edittext, as that will consume the onKeyPressed event.

    Hope this helps you out :)