I have found numerous examples of how to pause a countdowntimer in Android, but each of these examples utilises more than 1 button (pause, resume and cancel).
I want to have one button that when I press it the timer starts, then when I press it again it pauses (cancelling the original timer, capturing the timer value) and resumes when clicked again (taking the captured time from the pause to start off a new counterdowntimer).
Does anyone have an example of how to achieve this? I have tried if else loops in the onClick listener of the button. I have a very crude semi-working example;
if (gameOn == 1) {
if((clkOnTimerBtn % 2)==0) {
isPaused = true; // PAUSE COUNTDOWN TIMER
resumeCountDownTimer(view, "pause");
} else { // RESUME COUNTDOWN TIMER
resumeCountDownTimer(view, "resume");
}
The problem with the above is that this is carried out in the button onclick listener, so if a new CountDownTimer is created inside my resumeCountDownTimer its not possible to access the timer later on to cancel it (pause). I have also tried looking for a way to cancel all countdowntimers, messy if I could, but I couldn't find any examples or references to doing so as this would at least get the desired behaviour even if it isn't the most elegant way.
If I understood you correctly, something like this should work.
public class MainActivity extends AppCompatActivity {
CountDownTimer countDownTimer;
long duration = 100000; //This is the initial time,
long millisecondsLeft = 100000; // This is the time left. At the start it equales the duration.
boolean isCountDownTimerActive = false;
Button startButton;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
start = (Button) findViewById(R.id.startStop);
final TextView timeLeft = (TextView) findViewById(R.id.timeLeft);
start.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (isCountDownTimerActive) {
if (countDownTimer != null)
countDownTimer.cancel();
isCountDownTimerActive = false;
} else {
countDownTimer = new CountDownTimer(millisecondsLeft, 1000) {
#Override
public void onTick(long l) {
millisecondsLeft = l;
timeLeft.setText(" " + l);
}
#Override
public void onFinish() {
}
};
isCountDownTimerActive = true;
countDownTimer.start();
}
}
});
}
}
Related
I'm trying to do some example about countdown timer using Button and set OnclickListener for that Button. My Default value is 10 and it will be decrease each second, how can i reset my value back to 10?
CountDownTimer cannot be restarted, it can only be used once. You either have to create your own count down class that can handle being restarted, or just create a new instance of your CountDownTimer and cancel the old instance.
See the example code below where we have a CountDownTimer that counts down for 10 seconds in 1 second intervals, a Button that resets the timer when clicked (by cancelling the current timer and starting a new one), and a TextView that displays the time left in the current timer.
public class YourActivity extends Activity {
private CountDownTimer countDownTimer;
private TextView timerDisplayTextView;
private static final long TEN_SECONDS = TimeUnit.SECONDS.toMillis(10);
private static final long COUNTDOWN_INTERVAL = TimeUnit.SECONDS.toMillis(1);
#Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
Button myButton; // initialized here
// timerDisplayTextView initialized here
myButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
countDownTimer.cancel();
countDownTimer = getNewCountDownTimer(TEN_SECONDS);
countDownTimer.start();
showTimeInTextView(TEN_SECONDS);
}
});
countDownTimer = getNewCountDownTimer(TEN_SECONDS);
countDownTimer.start();
}
#Override
protected void onDestroy() {
super.onDestroy();
countDownTimer.cancel();
}
private void showTimeInTextView(long millisecondsLeft) {
timerDisplayTextView.setText(TimeUnit.MILLISECONDS.toSeconds(millisecondsLeft) + " seconds left");
}
private CountDownTimer getNewCountDownTimer(long length) {
return new CountDownTimer(length, COUNTDOWN_INTERVAL) {
#Override
public void onTick(long millisUntilFinished) {
showTimeInTextView(millisUntilFinished);
}
#Override
public void onFinish() {
}
};
}
}
I am working on a simple game where the user is timed to answer a question.
After each correct question the user's time is reduced.
Right now, the user starts with a time of 10s.
How to make my countDownTimer reduces the amount of time with let say 0.8 after each correct answer.
I have to mention that my timer adjusts a progress bar as well.
This is my code now:
...
private ProgressBar mProgressBar;
private CountDownTimer mCountDownTimer;
private long timer_length = 10*1000;
private long timer_interval = 500;
...
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mProgressBar = (ProgressBar)findViewById(R.id.progressBar);
mTrueBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//is the user right? if pressing True button
if(isMathProblemTrue == 1){
//user is correct
Toast.makeText(MainActivity.this,"Correct!",Toast.LENGTH_SHORT).show();
generateMathProblem();
mCountDownTimer.cancel();
createNStartTimer();
}else{
//user is incorrect
transferUserToStartScreen();
mCountDownTimer.cancel(); // cancel
}
}
});
}
private void createNStartTimer() {
mCountDownTimer = new CountDownTimer(timer_length,timer_interval) {
#Override
public void onTick(long millisUntilFinished) {
int progress = (int) (millisUntilFinished/100);
mProgressBar.setProgress(progress);
}
#Override
public void onFinish() {
mProgressBar.setProgress(0);
transferUserToStartScreen();
}
}.start();
}
I'm a begginer in android programming and trying to improve my knowledge. I want to make an app that is a regressive chronometer, like this: I insert the seconds I want in a text view named "seconds", then press a button and the app counts down the seconds (for example: 50, 49, 48, ..., 0) in another text view called, let's say... "timeRemaining".
How this can be done? I have read some other questions here, but to be honest, I could not understand them...
Well, I managed to do something here, The countdown is working, but only if I set the time directly on the code. I cannot find a way to implement the conversion of the number (text) entered in the text view to LONG and then use this value as the time to countdown.
There is no error when debugging, but when the simulator is about to run the app and opens the activity, it stop with the message "Unfortunately, app has stopped"
Here's the code, if anyone can help me finding what I'm missing, I'll be glad!
Thank you all!
public class cronometro extends Activity implements View.OnClickListener {
Long tempo3 = Long.parseLong(findViewById(R.id.tempo).toString());
private CountDownTimer countDownTimer;
private boolean timerStarted = false;
private Button buttonStart;
public TextView textView;
private final long startTime = tempo3 * 1000;
private final long interval = 1 * 1000;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_cronometro);
buttonStart = (Button) this.findViewById(R.id.button);
buttonStart.setOnClickListener(this);
textView = (TextView) this.findViewById(R.id.textView);
countDownTimer = new CountDownTimerActivity(startTime, interval);
textView.setText(textView.getText() + String.valueOf(startTime/1000));
}
#Override
public void onClick(View v) {
if (!timerStarted) {
countDownTimer.start();
timerStarted = true;
buttonStart.setText("PARAR");
} else {
countDownTimer.cancel();
timerStarted = false;
buttonStart.setText("REINICIAR");
}
}
public class CountDownTimerActivity extends CountDownTimer {
public CountDownTimerActivity(long startTime, long interval) {
super(startTime, interval);
}
#Override
public void onFinish() {
textView.setText("tempo esgotado!");
}
#Override
public void onTick(long millisUntilFinished) {
textView.setText("" + millisUntilFinished/1000);
}
}
}
I'm trying to create a mini-game loop in which the user has 10 seconds to click a button or loses the game. When I run the while game loop, I want the while loop to start the timer and then either wait for the timer to run out or the user to click a button. Also, when the code runs, the app crashes within the while loop. Not sure how to continue.
I'm rather new to android.
Thanks in advance.
public class MainGame extends Activity implements OnClickListener {
ProgressBar progress1;
Boolean gameon = true;
Button option1;
Button option2;
Button option3;
private CountDownTimer countDownTimer;
private final long startTime = 10*1000;
private final long interval= 100;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_game);
Log.d("Mark", "justCreated Completed");
initializebuttons();//also initializes timer, buttons, text, etc.
Log.d("Mark", "Initialize Buttons Function Completed");
maingameloop();
//Drawable draw = getResources().getDrawable(R.drawable.custom_progress_bar);
//progress1.setProgressDrawable(draw);
}
private void initializebuttons(){
option1 = (Button) findViewById(R.id.buttonchoice1);
option1.setOnClickListener(this);
option2 = (Button) findViewById(R.id.buttonchoice2);
option2.setOnClickListener(this);
option3 = (Button) findViewById(R.id.buttonchoice3);
option3.setOnClickListener(this);
countDownTimer = new MyCountDownTimer (startTime, interval);
Log.d("Mark", "Inside the initialize buttons function");
}
private void maingameloop(){
while (gameon){
Log.d("Mark", "while loop running");
countDownTimer.start();
}
}
public class MyCountDownTimer extends CountDownTimer {
public MyCountDownTimer(long startTime, long interval){
super (startTime, interval);
synchronized(this){
}
}
#Override
public void onFinish() {
option1.setBackgroundColor(getResources().getColor(R.color.LightGreen));
}
#Override
public void onTick(long millisUntilFinished) {
}
}
#Override
public void onClick(View v) {
switch(v.getId()){
case R.id.buttonchoice1:
break;
case R.id.buttonchoice2:
break;
case R.id.buttonchoice3:
default:
break;
}
}
}
With this
while (gameon){
Log.d("Mark", "while loop running");
countDownTimer.start();
}
you will run the code
countDownTimer.start();
with every iteration which I'm sure is not what you want. You don't need (want?) this while loop at all. Simply start the timer whenever you need then in onFinish() run the code that you want to run when time runs out and place this code in the Button click as well. Obviously you could put this all in one function and call that function from onFinish() and onClick() or whatever.
I would also suggest checking in onClick(), or the method which runs the code, to cancel the timer and initialize it to null.
I think I get what you are saying, and if so, try doing this
instead of initializeButtons(), do
countDownTimer = new MyCountDownTimer (startTime, interval);
countDownTimer.start();
and then in onStart() of your CountDownTimer call initializeButtons();
private void initializebuttons(){
option1 = (Button) findViewById(R.id.buttonchoice1);
option1.setOnClickListener(this);
option2 = (Button) findViewById(R.id.buttonchoice2);
option2.setOnClickListener(this);
option3 = (Button) findViewById(R.id.buttonchoice3);
option3.setOnClickListener(this);
Log.d("Mark", "Inside the initialize buttons function");
}
in onClick(View v), assuming that the answer and the text of the button are the same
if(v.getText().toString().equals(answer)){
// do what you would do if you win
win = true; // win is a private class boolean I've created for you
countDownTimer.cancel();
}
and then in onFinish()
if(!win){
// do what you want for a loss
}
This will make it so that you determine if a button is clicked within the limit. If so you win, if not you lose. This isn't exactly based on your code, but can be modified to work.
So I'm trying to write a stopwatch app that displays time in milliseconds, but for some reason it won't work. Basically I have just a togglebutton that, after being pressed, starts printing the milliseconds from the start time to the current time... In the simulator though, the app locks up. What's wrong?
public class testing extends Activity {
/** Called when the activity is first created. */
Button start,stop;
long init,now,time;
TextView display;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.test);
display = (TextView) findViewById(R.id.chronometer1);
final ToggleButton passTog = (ToggleButton) findViewById(R.id.onoff);
passTog.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
init=System.currentTimeMillis();
while(passTog.isChecked())
{
now=System.currentTimeMillis();
time=now-init;
display.setText("t: " + time);
}
}
});
}
}
You definitely should not run a busy loop like you are doing inside the OnClickListener. That's why the app locks up. You need to let the rest of the system have its say. Also, it doesn't make sense to update the display more than once every 30 milliseconds or so, since that's about the fastest that the human eye can track. Also, you might want to suspend your timer when the activity is paused. Here's a version that does all that:
public class testing extends Activity {
/** Called when the activity is first created. */
Button start,stop;
long init,now,time,paused;
TextView display;
Handler handler;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
handler = new Handler();
setContentView(R.layout.test);
display = (TextView) findViewById(R.id.chronometer1);
final ToggleButton passTog = (ToggleButton) findViewById(R.id.onoff);
final Runnable updater = new Runnable() {
#Override
public void run() {
if (passTog.isChecked()) {
now=System.currentTimeMillis();
time=now-init;
display.setText("t: " + time);
handler.postDelayed(this, 30);
}
}
};
passTog.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
init = System.currentTimeMillis();
handler.post(updater);
}
});
}
#Override
protected void onPause() {
super.onPause();
paused = System.currentTimeMillis();
}
#Override
protected void onResume() {
super.onResume();
init += System.currentTimeMillis() - paused;
}
}
You put the setText() method in your onClick(), so will you click the button every second?
Its not even a thread!
Try the onTick() method of CountDownTimer class instead.