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
Related
I am trying to make the countdown app from the movie Countdown. I am very new to coding.
The goal here is to update the textview that shows the number of seconds left to live.
Here is the java code I wrote to try to accomplish that. I know that the other aspects such as years, days, hours and minutes aren't finished yet.
import android.os.Bundle;
import android.os.CountDownTimer;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import java.util.Calendar;
public class MainActivity extends AppCompatActivity {
private TextView mTextViewCountDownYears;
private TextView mTextViewCountDownDays;
private TextView mTextViewCountDownHours;
private TextView mTextViewCountDownMinutes;
private TextView mTextViewCountDownSeconds;
private Button mButtonAccept;
private CountDownTimer mCountDownTimer;
private Boolean mTimerRunning;
long timeLeftToLive = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Calendar deathDay = Calendar.getInstance();
deathDay.set(2021,7,24,10,14,45);
Calendar today = Calendar.getInstance();
long diff = deathDay.getTimeInMillis() - today.getTimeInMillis();
timeLeftToLive = diff;
mTextViewCountDownYears = findViewById(R.id.text_view_countdown_years);
mTextViewCountDownDays = findViewById(R.id.text_view_countdown_days);
mTextViewCountDownHours = findViewById(R.id.text_view_countdown_hours);
mTextViewCountDownMinutes = findViewById(R.id.text_view_countdown_minutes);
mTextViewCountDownSeconds = findViewById(R.id.text_view_countdown_seconds);
mButtonAccept = findViewById(R.id.button_accept);
mButtonAccept.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
startTimer();
}
});
}
private void startTimer(){
mCountDownTimer = new CountDownTimer(timeLeftToLive, 1000) {
#Override
public void onTick(long millisUntilFinished) {
timeLeftToLive = millisUntilFinished;
updateTextView();
}
#Override
public void onFinish() {
}
};
}
private void updateTextView() {
long secondsLeft = timeLeftToLive / 1000;
String secondsLeftFormatted = String.format("%02d",secondsLeft);
mTextViewCountDownSeconds.setText(secondsLeftFormatted);
}
}
Your code looks good and you are so close to it working properly! You simply need to add a .start() to the end of your definition of CountDownTimer inside your startTimer() function (before the semi-colon).
Like this:
private void startTimer(){
mCountDownTimer = new CountDownTimer(timeLeftToLive, 1000) {
#Override
public void onTick(long millisUntilFinished) {
timeLeftToLive = millisUntilFinished;
updateTextView();
}
#Override
public void onFinish() {
}
}.start();
}
There's a great example for you to reference here if you need it
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
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 am trying to start a timer when activity created and be able to reset the timer back from zero if the same button is pressed but every time I press the button that initiates the set Interval it seems to be creating a new interval and not resetting the one that was already creating. Can someone help please? Here is my code
timer = (TextView) findViewById(R.id.timer_value);
Count = new CountDownTimer(time, 1000) {
public void onTick(long millisUntilFinished) {
timer.setText("Time Left: " + millisUntilFinished / 1000);
}
public void onFinish() {
timer.setText("OUT OF TIME!");
if (time < 10000) {
time = 10000;
}
AlertDialog.Builder builder = new AlertDialog.Builder(
TicTacToe.this);
builder.setMessage("You are Out of Time").setPositiveButton(
"Replay", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// reset the game environment.
Count.onFinish();
// Count.cancel();
Count.start();
new_game(player_name_1);
}
});
AlertDialog alert = builder.create();
alert.show();
}
}.start();
you can use timers
//in global
Timer myTimer
/**
* its kills runnable
*/
public void stopTimer(){
//handler.removeCallbacks(null); //it resets all timer which handler holds
myTimer.cancel();
}
public void setTimer(int time){//give it 5 for 5 secs
final Runnable Update = new Runnable() {
public void run() {
//do sth
}
};
myTimer = new Timer();
myTimerTimer.schedule(new TimerTask() {
#Override
public void run() {
handler.post(Update);
}
}, 1000, time*1000);
}
If you want to restart your timer, remove Count.onFinish();
Update:
I replaced AlertDialog with a new thread and here is the code that works on my emulator
public class MainActivity extends Activity
{
int time = 10000;
CountDownTimer Count;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final TextView timer = (TextView) findViewById(R.id.timer);
Count = new CountDownTimer(time, 1000) {
public void onTick(long millisUntilFinished) {
timer.setText("Time Left: " + millisUntilFinished / 1000);
}
public void onFinish() {
timer.setText("OUT OF TIME!");
if (time < 10000) {
time = 100000;
}
}
}.start();
}
public void buttonClicked(View view)
{
Log.i("Timer", "Resetting timer");
Count.cancel();
Count.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.