Coding a time condition together with an action

Viewed 75

When the app launch, I have a button (btn1) and a timer starting (long start = System.nanoTome();).

Now, two things can happen:

  • either the button is clicked at any time BEFORE the time limit of 1 minute (do some code_A then)
  • or the timer (long elapsedTime = System.nanoTome() - start;) reaches the time limit of 1 minute (do some code_B then)

I have tried lots of various combinations, but I stuck on the logic with regard to the time dimension and the if/while or whatever loop that would express/trigger BOTH the time condition OR the action condition (button btn1 pressed) in parallel.

Does anybody have an idea? That would be of great help.

2 Answers

You can use CountDownTimer and handle the state there, then invoke the proper method depending on the state:

Kotlin version:

class MyCountdownTimer: CountDownTimer(60000, 1000) {
    
    private var state: CountdownState = CountdownState.IDLE
    
    override fun onFinish() {
        state = CountdownState.FINISHED
    }

    override fun onTick(p0: Long) {
        if(state == CountdownState.IDLE) {
            state = CountdownState.COUNTING
        }
    }

    fun getState(): CountdownState {
        return state
    }
}

enum class CountdownState {
    IDLE, COUNTING, FINISHED
}

And in your code:


val countdownTimer = MyCountdownTimer()
btn1.setOnClickListener {
    countdownTimer.start()
}

btn2.setOnClickListener {
    if(countdownTimer.getState() == State.RUNNING) {
        callMethodWhenRunning()
    } else if (countdownTimer.getState == State.FINISHED) {
        callMethodWhenFinished()
   }
}

Java version:

import android.os.CountDownTimer;

public class MyCountdownTimer extends CountDownTimer {
    
    private CountdownState state = CountdownState.IDLE;
    
    public MyCountdownTimer(long millisInFuture, long countDownInterval) {
        super(millisInFuture, countDownInterval);
    }

    @Override
    public void onTick(long l) {
        if(state == CountdownState.IDLE) {
            state = CountdownState.COUNTING;
        }

    }

    @Override
    public void onFinish() {
        state = CountdownState.FINISHED;
    }
    
    public CountdownState getState() {
        return state;
    }
}

enum  CountdownState {
    IDLE, COUNTING, FINISHED
}

and usage:

MyCountdownTimer timer = new MyCountdownTimer(60000, 1000);
btn1.setOnClickListener(view -> {
    timer.start();
});
btn2.setOnClickListener(view -> {
    if(timer.getState() == State.RUNNING) {
        callMethodWhenRunning();
    } else if (timer.getState == State.FINISHED) {
        callMethodWhenFinished();
   }
});

You can use the CountDownTimer: https://developer.android.com/reference/android/os/CountDownTimer

        CountDownTimer countDownTimer = new CountDownTimer(10000, 1000) {
            @Override
            public void onTick(long l) {
            }

            @Override
            public void onFinish() {
                codeB();
            }
        }.start();
        Button button = new Button(this);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                countDownTimer.cancel();
                codeA();
            }
        });

This will create a timer with the length of 10 seconds and the onTick method is called every 1 second. new CountDownTimer(timerLength, tickInterval)

To further visualize your question in the comments, whether the timer stops or not:

Timer finishing normally.

In this screenshot, I've let the timer run out. The timer was set to 5 seconds and after 5 seconds onFinish() was called, as seen by the message.

Timer finishing prematurely.

In this screenshot, I've cancelled the timer through the onClickListener, as you can see there is no message in the center, thus onFinish() hasn't been called.

Related