I am making a course project and for this project, I will need to show a countdown timer. There will be a button which increments the timer by 5+ second. For example if the timer is set and started at 1:00 and if a user clicks the button, the timer must increase +5 like 1:05.
My code:
public class MainActivity extends Activity {
Button incrementTime, startTime;
public TextView timedisplay;
long millisInFuture = 1000;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
incrementTime = (Button) findViewById(R.id.button2);
startTime = (Button) findViewById(R.id.button3);
timedisplay = (TextView) findViewById(R.id.mycounter);
resetText();
incrementTime.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
millisInFuture += 1000;
resetText();
}
});
startTime.setOnClickListener(new OnClickListener(){
public void onClick(View v) {
CountDownTimer wavetimer = new myTimer(millisInFuture + 3000, 1000).start();
// ^ add 3 seconds.
}
});}
protected void resetText() {
timedisplay.setText("Time Left: " + millisInFuture / 1000);
}
public class myTimer extends CountDownTimer {
private long millisActual;
public myTimer(long millisInFuture, long countDownInterval) {
super(millisInFuture, countDownInterval);
millisActual = millisInFuture - 3000;
}
#Override
public void onTick(long millisUntilFinished) {
//v start showing the tick after 3 seconds.
if (millisUntilFinished <= millisActual) {
timedisplay.setText("Time Left: " + millisUntilFinished / 1000);
}
}
#Override
public void onFinish() {
timedisplay.setText("Countdown Finished");
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
}
My problem:
This works the same way I want but it only increments after the timer has finished running. I want it to increment during the countdown runtime!
You can use this class for your needs:
public abstract class MyCountDownTimer {
private CountDownTimer cdt;
private long millisInFuture;
private long countDownInterval;
public MyCountDownTimer(long millisInFuture, long countDownInterval) {
this.millisInFuture = millisInFuture;
this.countDownInterval = countDownInterval;
recreateCounter(millisInFuture, countDownInterval);
}
public abstract void onFinish();
public abstract void onTick(long millisUntilFinished);
public void start(){
cdt.start();
}
private void setMillisInFuture(long millisInFuture){
this.millisInFuture = millisInFuture;
}
public void onIncrement(long millis){
millisInFuture += millis;
recreateCounter(millisInFuture, countDownInterval);
}
private void recreateCounter(long millisInFuture, long countDownInterval){
if(cdt != null){
try {
cdt.cancel();
} catch (Exception e) {
}
}
cdt = new CountDownTimer(millisInFuture, countDownInterval) {
#Override
public void onTick(long millisUntilFinished) {
setMillisInFuture(millisUntilFinished);
MyCountDownTimer.this.onTick(millisUntilFinished);
}
#Override
public void onFinish() {
MyCountDownTimer.this.onFinish();
}
};
}
}
Related
I have a textview and i made a timer to decrease from 45 seconds to 0
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_forgot_password);
TextView textView = (TextView) findViewById(R.id.textView6);
t1 = (TextView)findViewById(R.id.t1);
b1 = (Button) findViewById(R.id.button1);
new CountDownTimer(45000, 1000) {
public void onTick(long millisUntilFinished) {
t1.setText("00:" + millisUntilFinished / 1000);
if(millisUntilFinished<=10000){
t1.setText("00:0" + millisUntilFinished / 1000);
}
}
public void onFinish() {
t1.setText("Tempo acabado");
b1.setEnabled(true);
}
}.start();
I want after the time has expired give the option for the user to click the b1 button and restart the timer
You can create instance of CountDownTimer, then when you need to restart you can perform cancel and start on that instance.
CountDownTimer countDownTimer = new CountDownTimer(45000, 1000) {
//......................
}
//Start at first
countDownTimer.start();
//Restart when button is pressed
b1.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
countDownTimer.cancel();
countDownTimer.start();
}
});
Is this what you want?
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_forgot_password);
TextView textView = (TextView) findViewById(R.id.textView6);
t1 = (TextView) findViewById(R.id.t1);
b1 = (Button) findViewById(R.id.button1);
b1.setOnClickListener(view -> restartTimer());
restartTimer();
}
private void restartTimer() {
b1.setEnabled(false);
new CountDownTimer(45000, 1000) {
public void onTick(long millisUntilFinished) {
t1.setText("00:" + millisUntilFinished / 1000);
if (millisUntilFinished <= 10000) {
t1.setText("00:0" + millisUntilFinished / 1000);
}
}
public void onFinish() {
t1.setText("Tempo acabado");
b1.setEnabled(true);
}
}.start();
}
I have made a CountDownTimer that works perfectly - you can get the correct time for soft/medium/hard-boiling an egg. My problem is that the timer resets after orientation change. I have googled and tried so many solution, still I don't understand how to use the onSave and onRestore properly. Here's my code:
Any tips?
package com.dohman.boilaneggbae;
import android.graphics.PorterDuff;
import android.os.CountDownTimer;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import java.util.Locale;
import java.util.concurrent.TimeUnit;
public class MainActivity extends AppCompatActivity {
private static final String CURRENT_TIME = "currentTime";
private static final String DURATION_TIME = "durationTime";
private long currentTime;
private int durationTime;
private TextView time;
private Button buttonLargeSize;
private Button buttonMediumSize;
private Button buttonSoft;
private Button buttonMedium;
private Button buttonHard;
private Button buttonHellaHard;
private CountDownTimer countDownTimer;
private EggSize mediumOrLarge = EggSize.UNDEFINED;
private boolean alreadyRunning = false;
enum EggSize {
UNDEFINED, MEDIUM, LARGE;
}
private View.OnClickListener btnMediumSizeClickListener = new View.OnClickListener() {
#Override
public void onClick(View view) {
mediumOrLarge = EggSize.MEDIUM;
}
};
private View.OnClickListener btnLargeSizeClickListener = new View.OnClickListener() {
#Override
public void onClick(View view) {
mediumOrLarge = EggSize.LARGE;
}
};
private View.OnClickListener btnSoftClickListener = new View.OnClickListener() {
#Override
public void onClick(View view) {
if ((mediumOrLarge != EggSize.UNDEFINED) && (alreadyRunning == false)) {
alreadyRunning = true;
durationTime = 240;
start(240);
} else if (mediumOrLarge == EggSize.UNDEFINED) {
time.setText("Choose size first");
} else {
alreadyRunning = false;
cancel();
}
}
};
#Override
protected void onSaveInstanceState(Bundle savedInstanceState) {
savedInstanceState.putLong(CURRENT_TIME, currentTime);
savedInstanceState.putInt(DURATION_TIME, durationTime);
super.onSaveInstanceState(savedInstanceState);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState != null) {
currentTime = savedInstanceState.getLong(CURRENT_TIME);
durationTime = savedInstanceState.getInt(DURATION_TIME);
}
time = findViewById(R.id.time);
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
currentTime = savedInstanceState.getLong(CURRENT_TIME);
durationTime = savedInstanceState.getInt(DURATION_TIME);
currentTime -= durationTime;
}
private void start(int duration) {
time.setText("");
if (mediumOrLarge == EggSize.MEDIUM) {
duration -= 60;
}
countDownTimer = new CountDownTimer(duration * 1000, 1000) {
#Override
public void onTick(long millisUntilFinished) {
String text = String.format(Locale.getDefault(), "%02d:%02d",
TimeUnit.MILLISECONDS.toMinutes(millisUntilFinished) % 60,
TimeUnit.MILLISECONDS.toSeconds(millisUntilFinished) % 60);
time.setText(text);
}
countDownTimer.start();
}
}
I finally solved this! Using this link:
https://codinginflow.com/code-examples/android/countdown-timer/part-2
Those are the codes:
package com.codinginflow.countdowntimerexample;
import android.os.CountDownTimer;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import java.util.Locale;
public class MainActivity extends AppCompatActivity {
private static final long START_TIME_IN_MILLIS = 600000;
private TextView mTextViewCountDown;
private Button mButtonStartPause;
private Button mButtonReset;
private CountDownTimer mCountDownTimer;
private boolean mTimerRunning;
private long mTimeLeftInMillis = START_TIME_IN_MILLIS;
private long mEndTime;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTextViewCountDown = findViewById(R.id.text_view_countdown);
mButtonStartPause = findViewById(R.id.button_start_pause);
mButtonReset = findViewById(R.id.button_reset);
mButtonStartPause.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (mTimerRunning) {
pauseTimer();
} else {
startTimer();
}
}
});
mButtonReset.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
resetTimer();
}
});
updateCountDownText();
}
private void startTimer() {
mEndTime = System.currentTimeMillis() + mTimeLeftInMillis;
mCountDownTimer = new CountDownTimer(mTimeLeftInMillis, 1000) {
#Override
public void onTick(long millisUntilFinished) {
mTimeLeftInMillis = millisUntilFinished;
updateCountDownText();
}
#Override
public void onFinish() {
mTimerRunning = false;
updateButtons();
}
}.start();
mTimerRunning = true;
updateButtons();
}
private void pauseTimer() {
mCountDownTimer.cancel();
mTimerRunning = false;
updateButtons();
}
private void resetTimer() {
mTimeLeftInMillis = START_TIME_IN_MILLIS;
updateCountDownText();
updateButtons();
}
private void updateCountDownText() {
int minutes = (int) (mTimeLeftInMillis / 1000) / 60;
int seconds = (int) (mTimeLeftInMillis / 1000) % 60;
String timeLeftFormatted = String.format(Locale.getDefault(), "%02d:%02d", minutes, seconds);
mTextViewCountDown.setText(timeLeftFormatted);
}
private void updateButtons() {
if (mTimerRunning) {
mButtonReset.setVisibility(View.INVISIBLE);
mButtonStartPause.setText("Pause");
} else {
mButtonStartPause.setText("Start");
if (mTimeLeftInMillis < 1000) {
mButtonStartPause.setVisibility(View.INVISIBLE);
} else {
mButtonStartPause.setVisibility(View.VISIBLE);
}
if (mTimeLeftInMillis < START_TIME_IN_MILLIS) {
mButtonReset.setVisibility(View.VISIBLE);
} else {
mButtonReset.setVisibility(View.INVISIBLE);
}
}
}
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putLong("millisLeft", mTimeLeftInMillis);
outState.putBoolean("timerRunning", mTimerRunning);
outState.putLong("endTime", mEndTime);
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
mTimeLeftInMillis = savedInstanceState.getLong("millisLeft");
mTimerRunning = savedInstanceState.getBoolean("timerRunning");
updateCountDownText();
updateButtons();
if (mTimerRunning) {
mEndTime = savedInstanceState.getLong("endTime");
mTimeLeftInMillis = mEndTime - System.currentTimeMillis();
startTimer();
}
}
}
EDIT: For some reason I can't mark my own answer as a solution, but this problem is solved anyway. (Answered)
Making a small game in Android Studio. Basically, the user will have a set amount of time to trigger a button press or the game will end. My CountDownTimer object is inside of a different function than my button click handler. How can I cancel the countDownTimer using cancel() from the button click handler.
Here is my code:
public countDownTimer timeLimit;
public void generate() {
final ProgressBar timer = (ProgressBar)findViewById(R.id.timer);`
int timeoutSeconds = 5000;
timer.setMax(timeoutSeconds);
timeLimit = new CountDownTimer(timeoutSeconds, 100) {
public void onTick(long millisUntilFinished) {
int timeUntilFinished = (int) millisUntilFinished;
timer.setProgress(timeUntilFinished);
}
public void onFinish() {
gameOver();
}
};
timeLimit.start();
}
public void buttonClicked(View v) {
timeLimit.cancel();
}
I'd be happy to hear any alternative ways to do this as well.
The code below works perfectly for me.
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private ProgressBar progressBar;
private CountDownTimer countDownTimer;
private Button stopTimerButton;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
progressBar = (ProgressBar)findViewById(R.id.progressBar);
stopTimerButton = (Button)findViewById(R.id.button);
stopTimerButton.setOnClickListener(this);
int timeoutSeconds = 5000;
progressBar.setMax(timeoutSeconds);
countDownTimer = new CountDownTimer(timeoutSeconds,100) {
#Override
public void onTick(long millisUntilFinished) {
int timeUntilFinished = (int) millisUntilFinished;
progressBar.setProgress(timeUntilFinished);
}
#Override
public void onFinish() {
}
};
countDownTimer.start();
}
#Override
public void onClick(View view) {
if(view == stopTimerButton){
countDownTimer.cancel();
}
}
}
I am creating a count down timer on the android platform.
I don't know how to store the remaining time on the timer (5 minutes on the timer) when the user presses the 'Stop' Button(PAUSE). So, if the user later presses the 'Start' Button again, it will continue counting down from where it left off. This is what i have done so far.
public class Timer_App extends Activity {
Button btn_Start, btn_Stop, btn_Reset;
TextView timer_text;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_timer_app);
//NEVER SLEEP!
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
//Buttons
btn_Start = (Button) findViewById(R.id.Start);
btn_Stop = (Button) findViewById(R.id.Stop);
btn_Reset = (Button) findViewById(R.id.Reset);
//FONT
Typeface typeface = Typeface.createFromAsset(getAssets(), "Digital_Font.TTF");
timer_text = (TextView) findViewById(R.id.timer_view);
timer_text.setTypeface(typeface);
//Timer
timer_text.setText("05:00);
final CounterClass timer = new CounterClass(300000, 1000);
//Start btn
btn_Start.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
timer.start();
}
});
//Stop btn
btn_Stop.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
timer.cancel();
}
});
//Reset btn
btn_Reset.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
}
});
}
//TIMER CLASS
public class CounterClass extends CountDownTimer{
public CounterClass(long millisInFuture, long countDownInterval) {
super(millisInFuture, countDownInterval);
}
#Override
public void onTick(long millisUntilFinished) {
String hms = String.format("%02d:%02d",
TimeUnit.MILLISECONDS.toMinutes(millisUntilFinished) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(millisUntilFinished)),
TimeUnit.MILLISECONDS.toSeconds(millisUntilFinished) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millisUntilFinished)));
timer_text.setText(hms);
}
#Override
public void onFinish() {
}
}
}
For some reason whenever I try to update my TextView to show how many seconds a person has left. But for some reason now it isn't working.
public class MainActivity extends Activity {
private int index=0;
#Override
protected void onCreate(Bundle savedInstanceState) {
final int[] Times= {6000,3000,7000,3000,4000,6000,3000};
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button = (Button) findViewById(R.id.button1);
final TextView textview =(TextView) findViewById(com.example.countdowntest.R.id.textView);
button.setOnClickListener(new OnClickListener(){
public void onClick(View v){
if(index<Times.length){
CountDownTimer timer = new CountDownTimer(
Times[index], 0) {
public void onTick(long millisUntilFinished) {
textview.setText("seconds remaining: "+ millisUntilFinished / 1000);
}
public void onFinish() {
textview.setText("done!");
index++;
}
}.start();
}
}
});
}
}
It should display the updated seconds until it is finished because it is all within the onClick method which doesn't end until the timer reaches zero.
Your countDownInterval is 0
CountDownTimer(long millisInFuture, long countDownInterval)
What you have
new CountDownTimer(Times[index], 0) { // second param to the constructor is 0.
Should be
new CountDownTimer(30000, 1000) // whatever value you like
http://developer.android.com/reference/android/os/CountDownTimer.html
It won't update because you are passing 0 try passing 1000 which will update it at 1 second interval