0

So I have a Start Button 1 where when it's clicked, it grabs the text from EditText1 and then calls CountDownTimer to call a method that passes the text from EditText1 through its parameters and display something in TextView1 every 10 seconds. However, if you decide to type something else in EditText1 and click the start button 1 again, it will call the CountDownTimer again.

In this case, there will be 2 "doThis" CountDownTimer variables, and doing doThis.cancel() will only cancel the second "doThis" CountDownTimer variable. I'm wondering how to fix this.

[EditText1]

[Start Button 1] [TextView1] [End Button 1]
[Start Button 2] [TextView2] [End Button 2]

CountDownTimer doThis;

doThis = new CountDownTimer(10000,10000)
    {
        @Override
        public void onTick(long millisUntilFinished) {

        }

        @Override
        public void onFinish() {
            start();
            TextView text = (TextView)findViewById(R.id.text);
            try {
                Date date = new Date(System.currentTimeMillis());
                text.setText(myMethod(variableFromEditText1));
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }.start();
frosty
  • 2,559
  • 8
  • 37
  • 73
  • Save the countDownTimer in a variable and then on the EndButton click call the countDownTimer.stop ? :) and maybe reset if you want to. – MadaManu Jan 08 '20 at 02:45
  • [cancel](https://developer.android.com/reference/android/os/CountDownTimer.html#cancel()) ? – Scary Wombat Jan 08 '20 at 02:45
  • @ScaryWombat but how do you make it know which one to cancel? There might be more than one running at the same time. – frosty Jan 08 '20 at 02:48
  • assign `new CountDownTimer` to a variable – Scary Wombat Jan 08 '20 at 02:49
  • @MadaManu how do you save the countDownTimer in a variable? something like countDownTimer theVariable = new countDownTimer? – frosty Jan 08 '20 at 02:49
  • yes. `CountDownTimer cdt = new CountDownTimer...` – MadaManu Jan 08 '20 at 02:51
  • And if there are more than one running at the same time, then have a `List` and then you use the index on the list to know which one is which to start / stop / reset – MadaManu Jan 08 '20 at 02:51
  • @MadaManu wait so I just do that and when i declare the new countdowntimer do i include all of the code i had above? – frosty Jan 08 '20 at 02:57
  • Yes. You'd just need to add `CountDownTimer cdt = ` in front of the existing code in the question and then when the stop button on click is triggered just call the cdt.cancel() as @ScaryWombat suggested. – MadaManu Jan 08 '20 at 03:00

2 Answers2

0

If you want to potentially have multiple timers and associated buttons/text views at the same time, I'd recommend you save them in a list. You'd need to "store" the timer CountDownTimer cdt = new CountDownTimer [...]. I would even make a wrapper to contain the start/end buttons, the text view and the timer itself. something like:

class MyTimer {

  Button start;
  Button end;
  TextView text;
  CountDownTimer cdt;

  // add here all required getters/setters and a constructor as needed
// the constructor of this wrapper can take details about the buttons location, text view location, and countdown amounts etc. or set them defaults as deemed necessary



}

Then in the MyTimer you can put all the logic of start/stop/reset in a methods with nice names that are called by the buttons registered event handlers.

Then have a list of as many MyTimers you want. List<MyTimer> myTimers = new ArrayList<>();

This List will help you keep track of how many you have, if you want to add more and allow you to configure and manage the bunch of timers you want.

MadaManu
  • 868
  • 4
  • 10
  • If button 1 is clicked twice, 2 countDownTimer is started, and if you click the end button 1 multiple times, it will only cancel the second click. Why is that and how do I fix it. – frosty Jan 08 '20 at 03:36
  • You would need to either update this question, or create a new one - it depends on which way you went into creating these in the end. – MadaManu Jan 08 '20 at 03:37
  • I edited the question, can you take a look, please? – frosty Jan 08 '20 at 03:54
  • Ok, you create the new CountDownTimer outside of the start event. Without calling `.start`. Then in the button pressed handle, you check if `doThis` is started, if not you call the `doThis.start()`. If it is started then you don't do anything. Similar for stop, in the stop button pressed handle you check if doThis is started, if it is then you stop, else you do nothing. – MadaManu Jan 08 '20 at 03:59
  • Then if you want two timers, then you create two at the top doThis1 and doThis2... each with start and stop on their buttons. – MadaManu Jan 08 '20 at 04:00
  • How do I check if it's started or not. Something like if (!doThis.start()) ??? – frosty Jan 08 '20 at 04:04
  • to check if the timer is running or not see the answers in this question: https://stackoverflow.com/questions/21451396/checking-if-countdowntimer-is-running – MadaManu Jan 08 '20 at 04:40
0

You should cancel the timer before assigning a new one to it - This way you will be able to keep track of it.

// Declare the timer as private variable to keep track of it
private CountDownTimer doThis;

// Method called once the Edit field is editted
public void onEdit() {
    // Check if timer isn't running already, in case it is, cancel it
    if (doThis != null)
        doThis.cancel();

    // And finally, assign the new timer
    doThis = new CountDownTimer(10000, 10000) {
        @Override
        public void onTick(long millisUntilFinished) {

        }

        @Override
        public void onFinish() {
            start();
            TextView text = (TextView) findViewById(R.id.text);
            try {
                Date date = new Date(System.currentTimeMillis());
                text.setText(myMethod(variableFromEditText1));
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }.start();
}

Edit: Obviously, this does allow you to run only one timer at a time - There has been some suggested and working ways to run multiple timers in comments already.