Issue
"How do I make a CountDown show at the same moment my Button gets enabled ?"
Additional info regarding the button: the Buttons Job is it to click 5 times through a stringarray displayed in a Textview to then get disabled for 5 seconds to do the same task again.
so ..I would like a CountDown to visually show those 5 seconds(the time the button is enabled) count down for the User to see.
sadly I dont have an idea how to connect my Button with an CountDown to let it know its supposed to count down at that particular time the Button is enabled.
Also I would like for the CountDown to start everytime the Button gets enabled.
I looked into https://developer.android.com/reference/android/os/CountDownTimer but it doesnt seem to have a solution for that particular case.
thats my Code for the Button as of now :
next_button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (currentnumber == list.length) {
currentnumber = 0;
}
if (Curclicks == mod - 1) {
next_button.setEnabled(false);
display.setText(list[currentnumber]);
currentnumber++;
handler.postDelayed(new Runnable() {
@Override
public void run() {
//the button will unlock after the delay specified
next_button.setEnabled(true);
Curclicks = 0;
}
}, delay);
} else {
display.setText(list[currentnumber]);
currentnumber++;
}
Curclicks++;
}
});
UI Thread code can solve that ? :
private void runThread() {
new Thread() {
public void run() {
while (delay == 5000) { //delay = 5000 ( 5 secs)
try {
runOnUiThread(new Runnable() {
@Override
public void run() {
timer.setText("" + delay);//timer=TxtView
}
});
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
Solution
Here is an example of how you can use the postDelayed()
method of the Handler
to create a count down. I have purposefully left the code a bit verbose so you can go through it step-by-step in order to see what is happening.
Create a few class variables and constants.
private static final long COUNT_DOWN_TICKS = 100l;
private static final long COUNT_DOWN_FINISH = 5000l;
private long countdownElapsed = 0l;
private Handler mCountDownHandler = new Handler();
COUNT_DOWN_FINISH
is set to 5000 --> 5 sec. But can be changed to anything you need. Also I use COUNT_DOWN_TICKS
set to 100 --> 0.1 sec, just in case you want to display a more precise count down.
From your OnClick()
method just call startCountDown()
to get the count down started.
private void startCountDown() {
try {
countdownElapsed = 0l;
next_button.setEnabled(false);
displayCountDown();
mCountDownHandler.postDelayed(mCountDownRunnable, COUNT_DOWN_TICKS);
}
catch (Exception ex){
Log.e(TAG, ex.getMessage());
}
}
private Runnable mCountDownRunnable = new Runnable() {
@Override
public void run() {
countdownElapsed = countdownElapsed + COUNT_DOWN_TICKS;
if(countdownElapsed >= COUNT_DOWN_FINISH){
releaseCountDownHandler();
next_button.setEnabled(true);
}
else{
mCountDownHandler.postDelayed(mCountDownRunnable, COUNT_DOWN_TICKS);
}
long secFull = countdownElapsed % 1000;
if(secFull == 0){
runOnUiThread(new Runnable() {
@Override
public void run() {
displayCountDown();
}
});
}
}
};
private void releaseCountDownHandler() {
try {
if(mCountDownRunnable != null) {
mCountDownHandler.removeCallbacks(mCountDownRunnable);
}
}
catch (Exception ex){
Log.e(TAG, ex.getMessage());
}
}
private void displayCountDown(){
long t = (COUNT_DOWN_FINISH - countdownElapsed)/1000;
String myTime = String.valueOf(t);
timer.setText(myTime);
}
In order to dispose of the Runnable
properly you will want to call releaseCountDownHandler()
from the onPause()
method. This is just a short running Thread
, but it should still not be ignored.
I prefer the Handler
with the postDelay()
method to the Thread.sleep()
method--something about putting any thread to sleep is disconcerting. Also note that it is a good idea to get accustom to checking the elapsed time condition with ">=" RATHER than "==" depending on the implementation (e.g. you use SystemClock.elapsedRealtime()
instead) the condition just might miss the exact value!
EDIT
Somewhere under the definition of your Activity
class (for this example I will call it MainActivity
) you will need to declare a few variables. Since they are being defined inside the class and NOT inside a method the are referred to as "class variables" and they have a scope of entire class when defined "private".
public class MainActivity extends AppCompatActivity {
//class variables
private static final long COUNT_DOWN_TICKS = 100l;
private static final long COUNT_DOWN_FINISH = 5000l;
private long countdownElapsed = 0l;
private Handler mCountDownHandler = new Handler();
private Button next_button;
private TextView timer;
....
}
You probably have declared the onClick()
method inside the onCreate()
method of the MainActivity
class. So just add the following code:
next_button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startCountDown();
}
Everything else I provide are method inside the MainActivity
class...NOT inside any other method. So below the onCreate()
method add all methods that I previously posted.
It will look something like this:
public class MainActivity extends AppCompatActivity {
private static final String TAG = MainActivity.class.getSimpleName();
//class variables
private static final long COUNT_DOWN_TICKS = 100l;
private static final long COUNT_DOWN_FINISH = 5000l;
private long countdownElapsed = 0l;
private Handler mCountDownHandler = new Handler();
private Button next_button;
private TextView timer;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// you must compensate for the actual layout for your activity
setContentView(R.layout.activity_main);
// you must compensate for the actual id of the TextView
timer = findViewById(R.id.tvTimer);
// you must compensate for the actual id of the Button
next_button = findViewById(R.id.btnNext);
next_button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startCountDown();
}
});
}
private void startCountDown() {
try {
countdownElapsed = 0l;
next_button.setEnabled(false);
displayCountDown();
mCountDownHandler.postDelayed(mCountDownRunnable, COUNT_DOWN_TICKS);
}
catch (Exception ex){
Log.e(TAG, ex.getMessage());
}
}
private Runnable mCountDownRunnable = new Runnable() {
@Override
public void run() {
countdownElapsed = countdownElapsed + COUNT_DOWN_TICKS;
if(countdownElapsed >= COUNT_DOWN_FINISH){
releaseCountDownHandler();
next_button.setEnabled(true);
}
else{
mCountDownHandler.postDelayed(mCountDownRunnable, COUNT_DOWN_TICKS);
}
long secFull = countdownElapsed % 1000;
if(secFull == 0){
runOnUiThread(new Runnable() {
@Override
public void run() {
displayCountDown();
}
});
}
}
};
private void releaseCountDownHandler() {
try {
if(mCountDownRunnable != null) {
mCountDownHandler.removeCallbacks(mCountDownRunnable);
}
}
catch (Exception ex){
Log.e(TAG, ex.getMessage());
}
}
private void displayCountDown(){
long t = (COUNT_DOWN_FINISH - countdownElapsed)/1000;
String myTime = String.valueOf(t);
timer.setText(myTime);
}
}
Answered By - Barns
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.