Similar query: wait until all threads finish their work in java
Hello,
I'm developing android application that contains some kind of count down timer. My problem is, that I have multiple count down timers, that sets text of TextView and have to work separately (first count down timer has to wait until the second one is finished etc.)
See code:
MyCountDownTimer.java
public class MyCountdownTimer extends CountDownTimer {
TextView tv;
// default constructor
public MyCountdownTimer (long millisInFuture, long countDownInterval) {
super(millisInFuture, countDownInterval);
}
// constructor
public MyCountdownTimer(int hours, int mins, int secs,
long countDownInterval, TextView tv) {
super(3600000 * hours + 60000 * mins + secs * 1000, countDownInterval);
this.tv = tv;
// all other settings
}
// when finished, set text of textview to done
#Override
public void onFinish() {
tv.setText("done!");
}
// when working periodically update text of text view to value of time left
#Override
public void onTick(long millisUntilFinished) {
tv.setText(/*function setting text of TextView based on time left*/);
}
}
Timer.java
public class Timer extends Fragment {
Button bStart;
Button bStop;
TextView tvShowTime;
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.timer, container, false);
}
public void onStart() {
super.onStart();
bStart = (Button) getView().findViewById(R.id.bTimerStart);
bStop = (Button) getView().findViewById(R.id.bTimerStop);
tvShowTime = (TextView) getView().findViewById(R.id.showTime);
// setting on button start click
bStart.setOnClickListener(new Button.OnClickListener() {
public void onClick(View v) {
timerStart();
}
});
// setting on button stop click
bStop.setOnClickListener(new Button.OnClickListener() {
public void onClick(View v) {
timerStop();
}
});
}
private void timerStart() {
bStart.setClickable(false);
int repeat = 2;
int hour, mins, secs;
for (int i = 0; i < 2 * repeat; i++) {
if (i % 2 == 0) {
// setting working count down timer values
mins = 1;
} else {
// setting resting count down timer values
secs = 30;
}
timerCount = new MyCountdownTimer(hours, mins, secs, REFRESH_RATE,
tvShowTime);
timerCount.start();
//////////////////////////////////////////////////
// HERE I WANT TO WAIT UNTIL COUNTDOWN IS DONE //
// ATM SECOND, THIRD AND FOURTH COUNT DOWN //
// TIMER IS STARTED //
//////////////////////////////////////////////////
}
}
-- EDIT --
At the end I did 2 CountDownTimers where first one calls in onFinish() second one and second one calls the first one until repeat = 0;
In final it was the best sotution for me. Anyway thanks for help, #Triode's answer helped me a lot
Start your SECOND, THIRD AND FOURTH COUNT DOWN TIMER in onFinish() of Your MyCountdownTimer
I think you have to put down the timerStop() method implementation and do not try to hide it,you need answer but you don't want others to benifit :s
Related
I have a widget with a button that users must press within a given interval. The button works fine and resets the interval but I want the button to change colour green -> amber -> red depending on time left. I have no problem changing the text on the button using remote views with code like this:
RemoteViews views =new RemoteViews(context.getPackageName(), R.layout.example_widget);
views.setCharSequence(R.id.example_widget_button, "setText", buttonText);
But I can not make any sort of code change the button colour. I've tried several things along the lines of:
views.setCharSequence(R.id.example_widget_button, "setBackgroundTint", "#039be5");
I have also tried using a drawable background and changing that. I'm missing something really obvious -it must be possible- I just can't find an example that works in my context.
Can anyone point me?
You can do this:
views.setInt(R.id.example_widget_button, "setBackgroundColor", android.graphics.Color.BLACK)`;
and you change the color to be what you want at that time.
You can either use Handler or CountDownTimer.
If you want to use Handler, here is the example:
long totalTime = 10000;
long warningTime = 6000;
long alertTime = 30000;
Runnable warningColorChangeRunnable = new Runnable() {
#Override
public void run() {
button.setBackgroundColor(getResources().getColor(R.color.colorWarning));
}
};
Runnable alertColorChangeRunnable = new Runnable() {
#Override
public void run() {
button.setBackgroundColor(getResources().getColor(R.color.colorAlert));
}
};
final Handler handler = new Handler();
handler.postDelayed(warningColorChangeRunnable, totalTime - warningTime);
handler.postDelayed(alertColorChangeRunnable, totalTime - alertTime);
button.setOnClickListener(new OnClickListener() {
#Override public void onClick(View view) {
handler.removeCallbacks(warningColorChangeRunnable);
handler.removeCallbacks(alertColorChangeRunnable);
}
});
If you want to use CountDownTimer, here is the example:
long totalTime = 10000;
long warningTime = 6000;
long alertTime = 30000;
long interval = 1000;
CountDownTimer timer = new CountDownTimer(totalTime, 1000) {
public void onTick(long millisUntilFinished) {
if (millisUntilFinished <= warningTime && millisUntilFinished > warningTime - interval) {
button.setBackgroundColor(getResources().getColor(R.color.colorWarning));
}
if (millisUntilFinished <= alertTime && millisUntilFinished > alertTime - interval) {
button.setBackgroundColor(getResources().getColor(R.color.colorAlert));
}
}
public void onFinish() {
// Maybe show a failure dialog
}
}.start();
button.setOnClickListener(new OnClickListener() {
#Override public void onClick(View view) {
timer.cancel();
}
});
I am trying to create a countdown timer that will increases its speed after a button press I uses the counter also to adjust a progress bar.
Right now I am adjusting the speed (increasing) after the button is pressed but it does not start from the beginning. For example, when I start my program the timer start from the beginning and decreases progressively, which is fine. However, when I press the button the counter does not start from the beginning like this:
I want just to make it run faster after each button press, not to decrease the length.
this is my code:
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();
timer_length *= 0.8;
timer_interval *= 0.8;
Log.d(TAG,"time length:"+timer_length);
Log.d(TAG,"time interval:"+timer_interval);
mCountDownTimer.cancel();
createNStartTimer();
//restartTimer();
}else{
//user is incorrect
transferUserToStartScreen();
//reset the timer
mCountDownTimer.cancel(); // cancel
}
}
});
private void createNStartTimer() {
mCountDownTimer = new CountDownTimer(timer_length,timer_interval) {
#Override
public void onTick(long millisUntilFinished) {
Log.d(TAG,"Mil until finish:"+millisUntilFinished);
int progress = (int) (millisUntilFinished/100);
mProgressBar.setProgress(progress);
}
#Override
public void onFinish() {
mProgressBar.setProgress(0);
transferUserToStartScreen();
}
}.start();
}
create 2 global constants outside the functions
int totalMillisUntilFinished = 0;
bool firstTime = true;
we initialize the totalMillisUntilFinished when onTick is called for the time, so update your your onTick function:
private void createNStartTimer() {
firstTime = true;
mCountDownTimer = new CountDownTimer(timer_length,timer_interval) {
#Override
public void onTick(long millisUntilFinished) {
if(firstTime){totalMillisUntilFinished = millisUntilFinished; firstTime = false;}
Log.d(TAG,"Mil until finish:"+millisUntilFinished);
int progress = (int) (millisUntilFinished*100/totalMillisUntilFinished);
mProgressBar.setProgress(progress);
}
Personally, I use Handlers and Runnables, which I would definitely suggest looking into instead.
I'm working on a countdown timer with user input on how many seconds to count down.
private void showTimer() {
myString = ((EditText)editTextTimer).getText().toString();
int countdownMillis = Integer.parseInt(myString) * 1000;
if (timer != null) {
timer.cancel();
}
timer = new CountDownTimer(countdownMillis, MILLIS_PER_SECOND) {
#Override
public void onTick(long millisUntilFinished) {
((TextView) countdownDisplay).setText("Counting down: " +
millisUntilFinished / MILLIS_PER_SECOND);
((TextView) countdownDisplay).setTextSize(25);
}
#Override
public void onFinish() {
((TextView)countdownDisplay).setText("Time's Up !");
((TextView)countdownDisplay).setTextSize(25);
}
}.start();
}
I'm doing this on a fragment. The problem is the text display of the "Time's Up" after I insert the time and click start. When clicking start again the timer will just start to display and countdown. As well the timer sometimes will skip 1 second.
Example user insert 10.
It will countdown from 10 , 9 , 7, 6, 5, 4, 3, 2, 1 - 8 is missing.
onCreatView
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_countDown, container, false);
countdownDisplay = rootView.findViewById(R.id.txtTimerLeft);
editTextTimer = rootView.findViewById(R.id.txtTimer);
startbutton = rootView.findViewById(R.id.button_start1);
startbutton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
try {
showTimer();
} catch (NumberFormatException e) {
e.printStackTrace();
}
}
});
return rootView;
}
Declaration
View editTextTimer;
View startbutton;
private static final int MILLIS_PER_SECOND = 1000;
int SECONDS_TO_COUNTDOWN;
View countdownDisplay;
private CountDownTimer timer;
String myString;
You are passing SECONDS_TO_COUNTDOWN * MILLIS_PER_SECONDand on first try it would 0, as well you initialize SECONDS_TO_COUNTDOWN it only inside showTimer function. Go that way:
private void showTimer() {
myString = ((EditText)editTextTimer).getText().toString();
int countdownMillis = Integer.parseInt(myString) * 1000;
Do not pass nothing in function and read value from editText. You can remove SECONDS_TO_COUNTDOWN at all. That's it.
I am working on making a clock similar to an abacus. My problem is that I cannot understand why my image resets after each second instead of continuing on to the right. My idea is that I need to use a different type of animation possibly? Here is my code so far:
public class MainActivity extends Activity implements AnimationListener {
Button start, stop;
TextView time;
LinearLayout layout;
Animation movement;
private Handler mHandler = new Handler();
private long startTime;
private long elapsedTime;
private final int REFRESH_RATE = 1000;
private String seconds;
private long secs;
private boolean stopped = false;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
start = (Button) findViewById(R.id.buttonStart);
start.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
// Start animation on each image
if(stopped){
startTime = System.currentTimeMillis() - elapsedTime;
}
else{
startTime = System.currentTimeMillis();
}
mHandler.removeCallbacks(startTimer);
mHandler.postDelayed(startTimer, 0);
}
});
stop = (Button) findViewById(R.id.buttonStop);
stop.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
mHandler.removeCallbacks(startTimer);
stopped = true;
}
});
time = (TextView) findViewById(R.id.textTime);
// Get the layouts
layout = (LinearLayout) findViewById(R.id.linearLayout1);
// Create animation for right image
movement = AnimationUtils.loadAnimation(this, R.layout.animation_test);
movement.setAnimationListener(this);
}
// Listen for animations to be finished
// There are more efficient ways, I'm just being lazy.
public void onAnimationEnd(Animation animation) {
// or do whatever it is you wanted to do here, like launch another activity?
}
public void onAnimationRepeat(Animation animation) {
}
public void onAnimationStart(Animation animation) {
}
private Runnable startTimer = new Runnable() {
public void run() {
elapsedTime = System.currentTimeMillis() - startTime;
update(elapsedTime);
mHandler.postDelayed(this,REFRESH_RATE);
}
};
private void update (float time){
secs = (long)(time/1000);
layout.startAnimation(movement);
secs = secs % 60;
seconds=String.valueOf(secs);
if(secs == 0){
seconds = "00";
}
if(secs <10 && secs > 0){
seconds = "0"+seconds;
}
/* Setting the timer text to the elapsed time */
((TextView)findViewById(R.id.textTime)).setText(seconds);
}
}
My animation.xml is as follows
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:fromXDelta="0"
android:toXDelta="15%p"
android:fromYDelta="0"
android:toYDelta="0%"
android:duration="500"
android:zAdjustment="top"/>
I am at a standstill, been trying to read through the Development Sections, I just can't find the right solution or must be overlooking something.
Try adding:
android:fillEnabled="true"
android:fillAfter="true"
to your animation.
If you are targeting Android 3.0 or later, you can use the new animation framework instead: http://developer.android.com/guide/topics/graphics/prop-animation.html
Okay, so I have a countdown timer, and my app requires the user to tap a button numerous times, however the timer starts ON that button tap. My problem is:
I have a 10 second countdown timer that starts at the press of the button, but instead of just continuing down to 0, it restarts at 10 everytime the user taps the button. How do I make it so when the user taps it the first time, it keeps counting down?
My code:
private Button tapBtn;
TextView cm;
tapBtn = (Button) findViewById(R.id.Tap);
cm = (TextView) findViewById(R.id.Timer);
final CountDownTimer aCounter = new CountDownTimer(10000, 1000) {
public void onTick(long millisUntilFinished) {
cm.setText("Time Left: " + millisUntilFinished / 1000);
}
public void onFinish() {
cm.setText("Time's Up!");
}
};
aCounter.cancel();
tapBtn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
scr = scr - 1;
TextView Score = (TextView) findViewById(R.id.Score);
Score.setText(String.valueOf(scr));
aCounter.start();
}
});
}
Are you trying to make it so that if the user has already started the timer, subsequent button presses don't restart it from the first tap? If so, all you should have to do is put an if statement in your onclick that checks to see if the timer is still counting down, i.e. check and see if the current time is greater than 0 on the counter.
Edit: here's code
final CountDownTimer aCounter = new CountDownTimer(10000, 1000) {
private long timeLeft;
public long getTimeLeft() {
return timeLeft;
}
public void onTick(long millisUntilFinished) {
timeLeft = millisUntilFinished / 1000;
cm.setText("Time Left: " + timeLeft);
}
public void onFinish() {
cm.setText("Time's Up!");
}
};
aCounter.cancel();
tapBtn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if (aCounter.getTimeLeft() == 0) {
scr = scr - 1;
TextView Score = (TextView) findViewById(R.id.Score);
Score.setText(String.valueOf(scr));
aCounter.start();
}
}
});
}
one way to do it is to create a flag that gets set on the first tap and have the onclick event flip the flag on the first click, and put the timer start inside of an if statement that only occurs if the flag hasn't been set.