I've got a listView that gets populated from a server. In the onClick of the ListItem, I display a button for a x number of seconds and I make it invisible again. How can I reset the time every time the onClick is called?
Here is my listItem onClick:
private void displayInCallButton() {
mButton.setEnabled(true);
if (canDisplayInCallControlls) {
canDisplayInCallControlls = false;
fadeInAnimation(mButton);
mButton.setEnabled(true);
mFrontView.postDelayed(new Runnable() {
public void run() {
fadeOutAnimation(mButton);
mButton.setEnabled(false);
hasAnimationEnded = true;
canDisplayInCallControlls = true;
}
}, 5000);
}
}
Thank you in advance.
You have to remove the callbacks and set it once again with the new one with the reset time.
first, set the call back like
Runnable myRunnable = new Runnable() {
#Override
public void run() {
fadeOutAnimation(mButton);
mButton.setEnabled(false);
hasAnimationEnded = true;
canDisplayInCallControlls = true;
}
};
then set it to mFrontView like,
mFrontView.postDelayed(myRunnable,5000)
If you want to reset, do it like
mFrontView.removeCallbacks(myRunnable);
mFrontView.postDelayed(myRunnable, 2000);
How can I reset the time every time the onClick is called?
There is no built-in mechanism to accomplish that.
You can, however, keep a reference to the Runnable you post, remove it and then repost it again to restart at the original delay.
The result would look somewhat like this in its most simple form:
Runnable mDelayedRunnable = new Runnable() {
#Override public void run() {
fadeOutAnimation(mButton);
mButton.setEnabled(false);
hasAnimationEnded = true;
canDisplayInCallControlls = true;
}
};
private void displayInCallButton() {
mButton.setEnabled(true);
if (canDisplayInCallControlls) {
canDisplayInCallControlls = false;
fadeInAnimation(mButton);
mButton.setEnabled(true);
mFrontView.removeCallbacks(mDelayedRunnable);
mFrontView.postDelayed(mDelayedRunnable, 5000);
}
}
You can safely call removeCallbacks() with a Runnable that was never posted in the first place (or even null).
If you don't want to keep an explicit reference to the Runnable, you could also opt to tag the view with it. Just don't forget to clean up on i.e. orientation changes and the like.
Related
I want to change from my current activity to another while I am inside a Handler. The idea is other code inside the handler will run until a certain condition doesnt match (with increment of the count value every time). When the count value matches the condition I close the activity and move to another.
my code is:
mHandler = new Handler();
mRunnable = new Runnable() {
#Override
public void run() {
if(count<CONDITION_VALUE)
{
//do other stuff...
count++;
}else
{
//change activity...
finish();
}
mHandler.postDelayed(mRunnable, 4000);
}
};
mHandler.postDelayed(mRunnable, (1000));
The code is running without any error but the old activity is not being destroyed (i guess) and the new activity is reloaded after every 4 seconds.
I want the new activity to load only once.
How can I achieve this?
try this, from enter link description here
in your Activity
#Override
public void onDestroy() {
mHandler.removeCallbacks(mRunnable);
super.onDestroy();
}
I have an if statement which checks if three slots are finished. If it is, the timer should stop, but the code is not running for some reason. I have seen a post similar to this If-condition never executes despite correct condition, however their solution solved nothing.
Here is my code:
Stop function
public void stop(ImageSwitcher slot){
slotOneFinished = (slot.equals(slotOne));
slotTwoFinished = (slot.equals(slotTwo));
slotThreeFinished = (slot.equals(slotThree));
if (slotOneFinished&&slotTwoFinished&&slotThreeFinished){
//not running
Toast.makeText(MainActivity.this, "Running",Toast.LENGTH_SHORT).show();
checkWin(getFruits());
timer.cancel();
timer = null;
}
}
Timer
private Timer timer;
TimerTask timerTask = new TimerTask() {
#Override
public void run() {
runOnUiThread(new TimerTask() {
#Override
public void run() {
if (!slotOneFinished){
animate(randomSwitchCount(), slotOne);
}
if (!slotTwoFinished) {
animate(randomSwitchCount(), slotTwo);
}
if (!slotThreeFinished) {
animate(randomSwitchCount(), slotThree);
}
}
});
}
};
Animate function
public void animate(final int maxCount, final ImageSwitcher slot) {
i++;
if (i<maxCount){
Animation in = AnimationUtils.loadAnimation(this, R.anim.new_slot_item_in);
Animation out = AnimationUtils.loadAnimation(this, R.anim.old_item_out);
slot.setInAnimation(in);
slot.setOutAnimation(out);
int fruit = randomFruit();
slot.setTag(fruit);
slot.setImageResource(fruit);
}else {
stop(slot);
}
}
Using == did nothing as well.
Thanks for your help,
PiNet
This condition can never be true, assuming that equals() is implemented in the canonical way, and slotOne, slotTwo, and slotThree are 3 distinct objects:
if (slotOneFinished&&slotTwoFinished&&slotThreeFinished)
Looks like you had a mistaken assumption about the scope of the variables. You can probably fix this by using a condition like this, instead:
if( slot == slotOne )
slotOneFinished = true;
...and so forth.
The Android Studio debugger is your friend.
I created one handler to repeat a task repeatedly and I also want to destroy it within that handler once a condition has been met.
pinHandler = new Handler();
Now I created two functions separately to start and stop the task.
void startRepeatingPins() {
mPinSetter.run();
}
Runnable mPinSetter = new Runnable() {
#Override
public void run() {
try{
System.out.println("PinIndwx count is :"+pinIndexCount);
if(pinIndexCount==(plist.size()-1))
{
stopUpdatingPins();
pinIndexCount=0;
//pinHandler.removeCallbacks(mPinSetter);
System.out.println("Handler stopped by itself.");
}
else
{
updatePoint(plist.get(pinIndexCount));
pinIndexCount++;
}
}
finally {
pinHandler.postDelayed(mPinSetter, pinInterval);
}
}
};
private void stopUpdatingPins()
{
pinIndexCount=0;
pinHandler.removeCallbacks(mPinSetter);
System.out.println("Called the stop function.");
}
Now, the issue is that, if I call the stopUpdatingPins function , the handler stops but when I try to stop it automatically from within the handler, it just doesn't stop. Although the stopUpdatingPins function does get called.
Change You startRepeatingPins() like this, You should not directly call the run. If your run like this then there is no point of removing this from Handler. So attach Runnable with Handler.
void startRepeatingPins() {
pinHandler.post(mPinSetter);
}
You added post delay in finally that means you are stopping at first if loop and starting again in finally, So it's never stopping. So Change your runnable like this,
Runnable mPinSetter = new Runnable() {
#Override
public void run() {
System.out.println("PinIndwx count is :"+pinIndexCount);
if(pinIndexCount==(plist.size()-1))
{
stopUpdatingPins();
pinIndexCount=0;
//pinHandler.removeCallbacks(mPinSetter);
System.out.println("Handler stopped by itself.");
}
else
{
updatePoint(plist.get(pinIndexCount));
pinIndexCount++;
pinHandler.postDelayed(mPinSetter, pinInterval);
}
}
};
I would like to set a background of a table to blink with the collors red + white every 500 millisec for start.The ideea is I want it to implement in this loop inside the program and I don't know how.
if(Integer.parseInt(feedback.getText().toString()) == 0)
{
showup.setText("0");
btnbool.setBackgroundColor(Color.RED);
btnbool.setText("FALSE");
}
I have searched on previous topics but I couldn't find something that work in my code, I don't know how to use a handler to make this happen.There won't be a problem if I call a function to do this.
In top of your Activity class implement these:
// isRed flag to set bg to red or white
boolean isRed = true;
Handler handler = new Handler();
MyThread thread = new MyThread();
private class MyThread implements Runnable {
public void run() {
showup.setText("0");
if (isRed){
btnbool.setBackgroundColor(Color.WHITE);
isRed=false;
}
else{
btnbool.setBackgroundColor(Color.RED);
isRed=true;
}
btnbool.setText("FALSE");
// will run every 500 milliseconds or whatever you wish
handler.postDelayed(thread, 500);
}
}
run your thread in your onCreate() :
handler.post(thread);
to start/stop thread onClick of Button:
on top of your activity:
boolean threadStart = true;
inside your onclick event:
if (threadStart){
handler.removeCallbacks(thread);
threadStart=false;
}
else{
handler.post(thread);
threadStart=true;
}
Timer or ScheduledExecutorService.
ScheduledExecutorService executorService = Executors.newScheduledThreadPool(1);
when you want to launch it
executorService.schedule(blinkRunnable, 500, TimeUnit.MILLISECONDS);
the runnable to execute:
private Runnable blinkRunnable = new Runnable(){
#Override
public void run() {
if(Integer.parseInt(feedback.getText().toString()) == 0)
{
showup.post(new Runnable() {
#Override
public void run() {
showup.setText("0");
btnbool.setBackgroundColor(Color.RED);
btnbool.setText("FALSE");
}
});
}
executorService.schedule(blinkRunnable, 500, TimeUnit.MILLISECONDS); // start again
}
}
P.S You could put the colors in an array, use an index and make something more flexible.
I have an app that shows a disclaimer at the beginning of the program. I want a button to remain invisible for a set amount of time, and then become visible.
I set up a thread that sleeps for 5 seconds, and then tries to make the button visible. However ,I get this error when I execute my code:
08-02 21:34:07.868: ERROR/AndroidRuntime(1401): android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
How can I count 5 seconds, and then make the button visible?
THanks.
Thread splashTread = new Thread() {
#Override
public void run() {
try {
int waited = 0;
while(_active && (!_ok2)) {
sleep(100);
if(_active) {
waited += 100;
if(waited >= _splashTime)
{
turnButtonOn();
}
}
}
} catch(InterruptedException e) {
// do nothing
} finally {
finish();
startActivity(new Intent("com.lba.mixer.Choose"));
}
};
splashTread.start();
public static void turnButtonOn() {
okButton.setVisibility(View.VISIBLE);
}
The problem is that you're not in the UI thread when you call okButton.setVisibility(View.VISIBLE);, since you create and run your own thread. What you have to do is get your button's handler and set the visibility through the UI thread that you get via the handler.
So instead of
okButton.setVisibility(View.VISIBLE)
you should do
okButton.getHandler().post(new Runnable() {
public void run() {
okButton.setVisibility(View.VISIBLE);
}
});
I found this to be a much simpler solution. Visibility on 7 second delay
continuebutton.setVisibility(View.INVISIBLE);
continuebutton.postDelayed(new Runnable() {
public void run() {
continuebutton.setVisibility(View.VISIBLE);
}
}, 7000);
I found this a Better solution to the problem
(button id = but_resend)
define handler
private Handler handler;
call function in extend class
showButtons();
define after class
private void showButtons() {
handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
((Button) findViewById(R.id.but_resend)).setVisibility(View.VISIBLE);
}
}, 20000); // produce 20 sec delay in button visibility
}
and keep in mind to hide the visibility in the.xml file by
android:visibility="invisible"