I have a CountDownTimer Class to set a countdown which will start will when the user clicks some Button.
This is the code that includes the CountDownTimer
public class play extends Activity implements View.OnClickListener{
private TapCountDownTimer countDownTimer;
private final long startTime = 10;
private final long interval = 1;
private TextView countdowntext;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.play);
countDownTimer = new TapCountDownTimer(startTime, interval);
countdowntext = (TextView)findViewById(R.id.countdowntext);
countdowntext.setText(String.valueOf(startTime));
Button buttonstart = (Button)findViewById(R.id.stopbutton);
buttonstart.setOnClickListener(new View.OnClickListener() {
public void onClick(View v){
countDownTimer.start();
}
});
Button buttonstop = (Button)findViewById(R.id.stopbutton);
buttonstop.setOnClickListener(new View.OnClickListener() {
public void onClick(View v){
countDownTimer.cancel();
}
});
public class TapCountDownTimer extends CountDownTimer {
public TapCountDownTimer(long startTime, long interval)
{
super(startTime, interval);
}
#Override
public void onTick(long millisUntilFinished)
{
countdowntext.setText(Long.toString(millisUntilFinished/1));
}
#Override
public void onFinish()
{
countdowntext.setText("Time's up!");
}
}
}
I set the text in this line
countdowntext.setText(Long.toString(millisUntilFinished/1));
But it's not working and the text shows "Time's Up" instead of the countdown.
Does anyone know how to fix this issue?
Your startTime and interval are erroneosly set in seconds.
Just multiply both by 1000, since you need milliseconds.
Also note that you don't need longs, for holding such low values.
Integers will do.
private final int startTime = 10000; // 10 secs
private final int interval = 1000; // 1s = 1000 ms
Also this has no meaning: millisUntilFinished/1 (dividing any number by 1 gives you the original number).
It must be millisUntilFinished / 1000
Related
I am new to android studio and want to overcome from this problem.
It gonna help me a lot while creating some future apps like , stopwatch, timer etc etc.
Thanks in advance !!
public class MainActivity extends AppCompatActivity {
private EditText k;
private Button start;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
k=findViewById(R.id.kf);
start=findViewById(R.id.startf);
start.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
for(int i=1;i<1000;i++)
{
k.setText(String.valueOf(i) );
}
}
});
}
}
As #f1sh already mentioned in the comments your for loop is executing at such a speed that all you see is the final value. For such cases in android one of the best solutions is to make use of Handler for posting delayed functions without blocking the UI.
So for showing 1 to 999 you can try something like this:
public class MainActivity extends AppCompatActivity {
private EditText k;
private Button start;
int count;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
k=findViewById(R.id.kf);
start=findViewById(R.id.startf);
final Handler handler = new Handler();
final Runnable runnable = new Runnable() {
public void run() {
if (count < 1000) {
k.setText(String.valueOf(count));
count++;
handler.postDelayed(this, 1000);
} else {
handler.removeCallbacks(this);
}
}
};
start.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
count = 1;
handler.postDelayed(runnable, 0);
}
});
}
}
this will keep changing the text in TextView with a 1 second delay, you can change the delay as needed by setting the milliseconds in runnable.
You can even use a countdown timer for this purpose but its more like a workaround and requires you to calculate the correct time etc.
For example displaying 1 to 10 would be something like this:
...
count = 1;
new CountDownTimer(11000, 1000) {
public void onTick(long millisUntilFinished) {
tv.setText(String.valueOf(count));
count++;
}
public void onFinish() {
}
}.start();
here you are displaying the value every 1 second for 11 seconds
In my game the user gets a point when he clicks a button within five seconds. Now I want the timer to decrease the time with every point the user gets - so e.g. with zero points the user has five seconds, and when he has one point he gets only 4.5 seconds to click it again and get the second point. Do I solve it with a for loop?
public class GameScreen extends Activity {
public int score = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_game);
Button count = (Button) findViewById(R.id.button1);
text = (TextView) this.findViewById(R.id.textView3);
tvscore = (TextView) findViewById(R.id.score);
timer();
}
public void gameover() {
Intent intent = new Intent(this, GameOverScreen.class);
startActivity(intent);
}
public void onClick (View view) {
score++;
tvscore.setText(String.valueOf(score));
timer();
}
public void timer(){
new CountDownTimer(5000, 10) {
public void onTick(long millisUntilFinished) {
text.setText(""+String.format("%02d:%03d",
TimeUnit.MILLISECONDS.toSeconds(millisUntilFinished) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millisUntilFinished)),
TimeUnit.MILLISECONDS.toMillis(millisUntilFinished) - TimeUnit.SECONDS.toMillis(TimeUnit.MILLISECONDS.toSeconds(millisUntilFinished))
));
if(animationRunning) {
cancel();
}
}
public void onFinish() {
text.setText("Too slow.");
gameover();
}
}.start();
}
}
What about doing this:
public void timer(float time) {
new CountDownTimer(time, 10) {
// YOUR CODE
}
}
public void onClick (View view) {
score++;
tvscore.setText(String.valueOf(score));
timer(Math.max(5000-score*500, 2000));
}
I suppose each click (score) will decrease the time with 500 millis...
Limit - Math.max(a, b) will choose the biggest value. Means when 5000-score*500 will be lower than 2000, it will choose 2000 millis instead
Only timer method:
public void timer() {
float time = Math.max(5000-score*500, 2000)
new CountDownTimer(time, 10) {
// YOUR CODE
}
}
I am supernoob programmer. I'm trying to make an adroid interval timer, where user inputs rounds, work time and break time. I can't find a way to start break timer after work timer, they start running at the same time. How should I go about it?
Thanks!
public class MainActivity extends Activity {
EditText rundy, praca, przerwa;
Button start;
TextView timer;
boolean timerHasStarted = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
rundy = (EditText) findViewById(R.id.rundy); // rounds
praca = (EditText) findViewById(R.id.praca); // work time
przerwa = (EditText) findViewById(R.id.przerwa); // break time
start = (Button) findViewById(R.id.start);
timer = (TextView) findViewById(R.id.timer);
start.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
int rundyL = Integer.parseInt(rundy.getText().toString())*1000;
long pracaL = Long.parseLong(praca.getText().toString()) * 1000;
long przerwaL = Long.parseLong(przerwa.getText().toString())*1000;
MyCountDownTimer countDownTimerPraca = new MyCountDownTimer(pracaL, 1000);
MyCountDownTimer countDownTimerPrzerwa = new MyCountDownTimer(przerwaL,1000);
for(int i = 0; i<rundyL; i++){
countDownTimerPraca.start();
countDownTimerPrzerwa.start();
}
}
class MyCountDownTimer extends CountDownTimer {
public MyCountDownTimer(long pracaL, long interval) {
super(pracaL, interval);
}
#Override
public void onTick(long millisUntilFinished) {
timerHasStarted = true;
long minutes = (millisUntilFinished / 1000)/60;
long seconds = (millisUntilFinished/1000)%60;
timer.setText( String.format("%02d", minutes) + ":" + String.format("%02d", seconds));
}
#Override
public void onFinish() {
timerHasStarted = false;
timer.setText("Times up");
}
}
});
}
}
public class MainActivity extends Activity {
EditText rundy, praca, przerwa;
Button start;
TextView timer;
boolean timerHasStarted = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
rundy = (EditText) findViewById(R.id.rundy); // rounds
praca = (EditText) findViewById(R.id.praca); // work time
przerwa = (EditText) findViewById(R.id.przerwa); // break time
start = (Button) findViewById(R.id.start);
timer = (TextView) findViewById(R.id.timer);
start.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
int rundyL = Integer.parseInt(rundy.getText().toString())*1000;
long pracaL = Long.parseLong(praca.getText().toString()) * 1000;
long przerwaL = Long.parseLong(przerwa.getText().toString())*1000;
MyCountDownTimer countDownTimerPrzerwa = new MyCountDownTimer(przerwaL,1000);
MyCountDownTimer countDownTimerPraca = new MyCountDownTimer(countDownTimerPrzerwa,pracaL, 1000);
for(int i = 0; i<rundyL; i++){
countDownTimerPraca.start();
}
}
class MyCountDownTimer extends CountDownTimer {
private MyCountDownTimer mytimer;
public MyCountDownTimer(long pracaL, long interval) {
super(pracaL, interval);
}
public MyCountDownTimer(MyCountDownTimer timer, long pracaL, long interval) {
this(pracaL, interval);
this.timer = timer;
}
#Override
public void onTick(long millisUntilFinished) {
timerHasStarted = true;
long minutes = (millisUntilFinished / 1000)/60;
long seconds = (millisUntilFinished/1000)%60;
timer.setText( String.format("%02d", minutes) + ":" + String.format("%02d", seconds));
}
#Override
public void onFinish() {
timerHasStarted = false;
timer.setText("Times up");
if(mytimer!=null)
mytimer.start();
}
}
});
}
}
I have question i have a chronometer in my app, when i back to my main window, and get back to Timer activity, I just want to resume a time on chronometer from CountDownTimer, how to to this ? Bundle doesn't help me and similar topics :( I will be very gratefull for any help.
public class Timer extends Activity {
private boolean start = false; // Semafor to button
private Chronometer timer; // Chronometr
private CountDownTimer count; // CountDown class
private final long startTime = 30 * 1000; // High
private final long end = 1 * 1000; //LOw
private ImageButton startB; // Button
private int VIBRATION_TIME = 1000; //vibration time
private Bundle state = new Bundle(); //button state
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_timer);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
// Show the Up button in the action bar.
getActionBar().setDisplayHomeAsUpEnabled(true);
}
this.timer = ((Chronometer) findViewById(R.id.chronometer1));
count = new MyCountDownTimer(startTime, end);
timer.setText("00:" + String.valueOf(startTime / 1000));
startB = (ImageButton) this.findViewById(R.id.start_pause);
startB.setBackgroundResource(R.drawable.start_button);
startB.setOnClickListener(new View.OnClickListener() {
// click init
#Override
public void onClick(View v) {
start = !start;
if (start == true) {
count.start(); // start count
startB.setBackgroundResource(R.drawable.stop_button);
} else {
count.cancel(); // pause count
startB.setBackgroundResource(R.drawable.start_button);
}
}
});
}
....
#Override
protected void onResume() {
super.onResume();
start = state.getBoolean("Button");
}
#Override
protected void onPause() {
super.onPause();
state.putBoolean("Button", start);
//count.cancel(); I don't wanna this!
}
class MyCountDownTimer extends CountDownTimer {
public MyCountDownTimer(long startTime, long interval) {
super(startTime, interval);
}
#Override
public void onFinish() {
timer.setText("00:00");
// TO DO :
Vibrator v = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
v.vibrate(VIBRATION_TIME);
startB.setBackgroundResource(R.drawable.start_button);
}
#Override
public void onTick(long millisUntilFinished) {
long tmp = millisUntilFinished / 1000;
timer.setText("00:" + tmp);
}
}
}
Make use of onSaveInstanceState. Override this method, and save your current time into the Bundle. Then, on onCreate, extract the value from the Bundle and apply it to your View.
Hmm yes that is correct what Alex says but I have new idea. CountDownTimer start count, we click backButton activity is killed, but CountDownTimer still counting, but when I use this activity again, I can run new timer and this is crazy, there is any way to do this like that : In create method we check that CountDownTimer is still running and we just update a chronometer, but if not we create everything from new? At now my solutions is tricky: override the onBackPressed() and add this moveTaskToBack(true); but this not back to my mainActivity but return to telephone screen.
I'm trying to make an application that has multiple buttons, and when each button is pressed, it will start a new timer and display the time on the text view assigned to that button. I have successfully made one of the buttons create a working timer, however I'm having trouble making another button do the same thing for a different text view. I do not know how to create multiple onCLick methods.
EDIT: I'm trying to make wolvesbutton do the same thing as wratihsbutton, but have a separate timer, and display it on a different text view.
Here is what I have so far:
import java.util.Timer;
import java.util.TimerTask;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.Handler.Callback;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends Activity {
TextView textView5, textView6, textView7;
long starttime = 0;
//this posts a message to the main thread from our timertask
//and updates the textfield
final Handler h = new Handler(new Callback() {
#Override
public boolean handleMessage(Message msg) {
long millis = System.currentTimeMillis() - starttime;
int seconds = (int) (millis / 1000);
int minutes = seconds / 60;
seconds = seconds % 60;
textView5.setText(String.format("%d:%02d", minutes, seconds));
return false;
}
});
//runs without timer be reposting self
Handler h2 = new Handler();
Runnable run = new Runnable() {
#Override
public void run() {
long millis = System.currentTimeMillis() - starttime;
int seconds = (int) (millis / 1000);
int minutes = seconds / 60;
seconds = seconds % 60;
textView5.setText(String.format("%d:%02d", minutes, seconds));
h2.postDelayed(this, 500);
if(seconds >= 10 || minutes >= 1){
textView5.setText("Ready");
}
}
};
//tells handler to send a message
class firstTask extends TimerTask {
#Override
public void run() {
h.sendEmptyMessage(0);
}
};
//tells activity to run on ui thread
class secondTask extends TimerTask {
#Override
public void run() {
MainActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
long millis = System.currentTimeMillis() - starttime;
int seconds = (int) (millis / 1000);
int minutes = seconds / 60;
seconds = seconds % 60;
textView6.setText(String.format("%d:%02d", minutes, seconds));
}
});
}
};
class wolvesFirstTask extends TimerTask {
#Override
public void run() {
h.sendEmptyMessage(0);
}
};
//tells activity to run on ui thread
class wolvesSecondTask extends TimerTask {
#Override
public void run() {
MainActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
long millis = System.currentTimeMillis() - starttime;
int seconds = (int) (millis / 1000);
int minutes = seconds / 60;
seconds = seconds % 60;
textView6.setText(String.format("%d:%02d", minutes, seconds));
}
});
}
};
Timer wraiths = new Timer();
Timer wolves = new Timer();
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView5 = (TextView)findViewById(R.id.textView5);
textView6 = (TextView)findViewById(R.id.textView5);
Button wraithsbutton = (Button)findViewById(R.id.wraithsb);
Button wolvesbutton = (Button)findViewById(R.id.wolvesb);
wraithsbutton.setText("Start");
wraithsbutton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Button wraithsbutton = (Button)v;
if(wraithsbutton.getText().equals("Stop")){
wraiths.cancel();
wraiths.purge();
h2.removeCallbacks(run);
wraithsbutton.setText("Start");
}else{
starttime = System.currentTimeMillis();
wraiths = new Timer();
wraiths.schedule(new firstTask(), 0,500);
wraiths.schedule(new secondTask(), 0,500);
h2.postDelayed(run, 0);
wraithsbutton.setText("Stop");
}
}
});
}
}
You need to add implement keyword after the extending the class
and then you have to override the onClick method like this
public class Example extends Activity implements OnClickListener {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.menulayout);
Button button1 = (Button) findViewById(R.id.b1);
button1.setOnClickListener(this);
Button button2 = (Button) findViewById(R.id.b2);
button2.setOnClickListener(this);
Button button3 = (Button) findViewById(R.id.b3);
button3.setOnClickListener(this);
}
#Override
public void onClick(View v) {
if(v.getId() == R.id.b1)
{
//do something here if button1 is clicked
}
else if (v.getId() == R.id.b2)
{
//do something here if button2 is clicked
}
else if (v.getId() == R.id.b3)
{
//do something here if button3 is clicked
}
}
}
An unrelated suggestion; I'd pull out the time display into a method, as the same code is in 4 places.
private void showElapsedTime(long elapsedTime, TextView textView) {
int seconds = (int) (elapsedTime / 1000);
int minutes = seconds / 60;
seconds = seconds % 60;
textView.setText(String.format("%d:%02d", minutes, seconds));
}
private void showElapsedTimeOnUiThread(final long elapsedTime, final TextView textView) {
runOnUiThread(new Runnable() {
#Override
public void run() {
showElapsedTime(elapsedTime, textView);
}
});
}
Call these methods from the 4 locations.
E.g.
Runnable run = new Runnable() {
#Override
public void run() {
showElapsedTime(System.currentTimeMillis() - starttime, textView5);
and
class secondTask extends TimerTask {
#Override
public void run() {
showElapsedTimeOnUiThread(System.currentTimeMillis() - starttime, textView6));
}
for example.
basically something like this:
public class MyButton extends Button implements View.OnClickListener{
private TextView tv; /// or ArrayList<TextView> tvs;
public MyButton(Context context,TextView tv) {
super(context);
this.tv = tv; ///your text views to be set make as many as you want or pass an array of text views if you like List<? extends TextView> as a constructor param
setOnClickListener(this);
}
public void onClick(View view) {
//run your tasks here
//set the textviews as you like -
}
public MyButton(Context context, AttributeSet attrs) {
super(context, attrs);
setOnClickListener(this);
}
public MyButton(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
setOnClickListener(this);
}
}
hope it will give you some ideas