I want an app which changes background color when pressing a button. After 500 ms, I want to change background color to black for 2000ms. And then repeat whole process again, until user terminates that.
I have following code but its not working as I think it should.
private void set() {
rl.setBackgroundColor(Color.WHITE);
timer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
runOnUiThread(new Runnable() {
#Override
public void run() {
rl.setBackgroundColor(Color.BLACK);
set(); // can I do that?
}
});
}
}, 500);
}
Can someone point me to right direction how can I do that? So I want:
Execute some code
After X time passed by , I want to execute another code and it should stay that way for X amount of time
Repeat process until user cancels that.
Something like this should work I think
Handler handler = new Handler();
Runnable turnBlack = new Runnable(){
#Override
public void run() {
myView.setBackgroundColor(Color.BLACK);
goWhite();
}};
Runnable turnWhite = new Runnable(){
#Override
public void run() {
myView.setBackgroundColor(Color.White);
goBlack();
}};
public void goBlack() {
handler.postDelayed(turnBlack, 500);
}
public void goWhite() {
handler.postDelayed(turnWhite, 2000);
}
There is much easier way to do this using AnimationDrawable:
AnimationDrawable drawable = new AnimationDrawable();
ColorDrawable color1 = new ColorDrawable(Color.YELLOW);
ColorDrawable color2 = new ColorDrawable(Color.BLACK);
// First color yellow for 500 ms
drawable.addFrame(color1, 500);
// Second color black for 2000 ms
drawable.addFrame(color2, 2000);
// Set if animation should loop. In this case yes it will
drawable.setOneShot(false);
Button btn = (Button)findViewById(R.id.button1);
btn.setBackground(drawable);
findViewById(R.id.buttonLan).setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// Start animation
((AnimationDrawable)v.getBackground()).start();
}
});
Related
In my Android app I simulate a button click with the following code :
void clickButton(final Button b, int delay)
{
final Handler handler = new Handler();
handler.postDelayed(new Runnable()
{
public void run()
{
final Drawable drawable = b.getBackground();
b.performClick();
b.getBackground().setColorFilter(b.getContext().getResources().getColor(R.color.colorAccent), PorterDuff.Mode.MULTIPLY);
// b.setBackgroundColor(Color.rgb(88, 166, 198));
b.setPressed(true);
b.invalidate();
// delay completion till animation completes
b.postDelayed(new Runnable() { //delay button
public void run() {
b.setPressed(false);
b.invalidate();
b.setBackground(drawable);
//any other associated action
}
}, 800); // .8secs delay time
}
}, delay);
}
But the color of the button will stay green after a click, how to get it back to the color before the click, after a .5 sec delay?
b.setBackgroundColor(ContextCompat.getColor(b.getContext(), R.color.colorAccent));
b.postDelayed(new Runnable() {
public void run() {
b.setBackgroundColor(ContextCompat.getColor(b.getContext(), R.color.initialColor));
}
}, 800);
I'm just trying to change the color of my drawn circle with a timer. I have implemented following code into my "onCreate" method:
Timer t = new Timer();
t.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
runOnUiThread(new Runnable() {
#Override
public void run() {
Drawing.switchColor();
}
});
}
},
1000,
1000);
The method switchColor() does the following action:
public static void switchColor() {
Random r = new Random(30);
int random = r.nextInt();
if(random < 10) {
p.setColor(Color.GREEN);
}
else if(random >10 && random < 20) {
p.setColor(Color.BLUE);
}
else {
p.setColor(Color.RED);
}
}
When I run this, the color stays at it's default.
Does anyone know whether I have to use a handler within or a different timer model?
Thanks in advance!
I now found a suitable solution:
//-------------------Part 1 of AddCircleTimer------------------------
//Declare the timerAddCircle
timerAddCircle = new Timer();
timerAddCircle.schedule(new TimerTask() {
#Override
public void run() {
TimerMethodAddCircle();
}
}, 1000, 1000);
//-------------------Part 2 of AddCircleTimer------------------------
private void TimerMethodAddCircle()
{
//This method is called directly by the timer and runs in the same thread as the timer.
//We call the method that will work with the UI through the runOnUiThread method.
this.runOnUiThread(Timer_Add);
}
private Runnable Timer_Add = new Runnable() {
public void run() {
//This method runs in the same thread as the UI.
//Do something to the UI thread here
Drawing.addCircle();
d.invalidate();
}
};
//-------------------END Part 2 of AddCircleTimer------------------------
This works very fine and I can use it for even more timers and different methods!
Thanks to all!
Your t.start() is missing, either in onCreate, onStart, or onResume, depending on when you want to start your timer.
I am writing simple game, where some action must accelerating during the process. The question is how to change timer's period?
timer = new Timer();
timerTask = new TimerTask() {
#Override
public void run() {
runOnUiThread(new Runnable() {
#Override
public void run() {
//
// I need to change timer's period here
//
}
});
}
};
timer.schedule(timerTask, 0, period);
Will be glad to hear any advices.
I assume that you are performing some logic within the run() method of the TimerTask.
I think a simpler way to go about this would be to use a Handler. This is possibly more idiomatic for Android:
private final Handler mHandler = new Handler();
private final Runnable mTask = new Runnable() {
#Override
public void run() {
// Do your logic.
// Now post again.
mHandler.postDelayed(mTask, /* choose a new delay period */);
}
};
public void init() {
delay = 1000L; // 1 second.
mHandler.postDelayed(mTask, delay);
}
I need to have my TextView be blue for half a second, and then turn white again (user clicks, it blinks blue).
To do this, I tried setting the colour to blue, setting a 500ms timer, and then changing it back to white. Like this:
// defining the TextView
final TextView showDatabase = new TextView(this);
showDatabase.setText("Show Database");
showDatabase.setTextColor(Color.WHITE);
// click listener
showDatabase.setOnClickListener (new View.OnClickListener() {
public void onClick(View v) {
showDatabase.setTextColor(Color.BLUE); // make it blue
// wait 500ms, then make it white again
Timer timer = new Timer();
timer.schedule(new TimerTask() {
#Override
public void run() {
showDatabase.setTextColor(Color.WHITE);
}
}, 500);
}
});
Logcat:
Only the original thread that created a view hierarchy can touch its views.
I can't simply create an instance of the TextView inside the timer function (I think) because it's not an element on a layout.
How can I let myself manipulate the TextView from inside the timer function?
Timer runs on a different thread. You cannot update ui from there. Use a Handler or runOnUiThread.
runOnUiThread(new Runnable() {
#Override
public void run() {
showDatabase.setTextColor(Color.WHITE);
}
});
Using Handler
Handler m_handler;
Runnable m_handlerTask ;
m_handler = new Handler();
m_handlerTask = new Runnable()
{
#Override
public void run() {
showDatabase.setTextColor(Color.WHITE);
m_handler.postDelayed(m_handlerTask, 500);
}
};
m_handlerTask.run();
To cancel
m_handler.removeCallbacks(m_handlerTask);
Add a runOnUiThread in your timer:
Timer timer = new Timer();
timer.schedule(new TimerTask() {
#Override
public void run() {
runOnUiThread(new Runnable() {
#Override
public void run() {
// do UI updates here
}
});
}
}, 500);
I wanted to delay a for loop without using Thread.sleep because that method make my whole application hang. I tried to use handler but it doesn't seems to work inside a loop. Can someone please point out the mistake in my code.
public void onClick(View v) {
if (v == start)
{
for (int a = 0; a<4 ;a++) {
Handler handler1 = new Handler();
handler1.postDelayed(new Runnable() {
ImageButton[] all= {btn1, btn2, btn3, btn4};
btn5 = all[random.nextInt(all.length)];
btn5.setBackgroundColor(Color.RED);
#Override
public void run() {
}
}, 1000);
}
}
}
Basically what I wanted to do is that I got 4 ImageButton and I change each of their background to red by using a loop in order. Thats why I need a delay inside my loop, if not all the ImageButton will just directly turn red without showing which ImageButton turn first.
Your for loop should be:
final ImageButton[] all= {btn1, btn2, btn3, btn4};
Handler handler1 = new Handler();
for (int a = 1; a<=all.length ;a++) {
handler1.postDelayed(new Runnable() {
#Override
public void run() {
ImageButton btn5 = all[random.nextInt(all.length)];
btn5.setBackgroundColor(Color.RED);
}
}, 1000 * a);
}
}
This way it achieves your desired behavior of staggering the color change.
Edited for syntax
You can use a Handler instead of for loop. You should not call Thread.sleep() on the UI thread.
final Handler handler = new Handler();
Runnable runnable = new Runnable() {
#Override
public void run() {
// do something
handler.postDelayed(this, 1000L); // 1 second delay
}
};
handler.post(runnable);
The following code doing the task in every second:
final Handler handler = new Handler();
Runnable task = new Runnable() {
#Override
public void run() {
Log.d(TAG, "Doing task");
handler.postDelayed(this, 1000);
}
};
handler.post(task);
Try this :
public void onClick(View v) {
if (v == start) {
for (int a = 0; a<4 ;a++) {
Handler handler1 = new Handler();
handler1.postDelayed(new Runnable() {
ImageButton[] all= {btn1, btn2, btn3, btn4};
#Override
public void run() {
btn5 = all[random.nextInt(all.length)];
btn5.setBackgroundColor(Color.RED);
}
}, 1000);
}
}
}
Example for Delay :
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
// Do something after 5s = 5000ms
buttons[inew][jnew].setBackgroundColor(Color.Red);
}
}, 5000);