How to make a Button blink in Android? - android

If the user (in my quizgame) chooses the false answer, the button with the correct answer should blink green.
So far i did it like this:
if(answerTrue)
for (int i = 0; i < 2000; i = i + 250) {
handler.postDelayed(rbl_blinkNormal, i);
i = i + 250;
handler.postDelayed(rbl_blinkGreen, i);
}
And the runnables:
Green:
rbl_blinkGreen= new Runnable() {
#Override
public void run() {
btn_richtig.setBackgroundResource(R.drawable.color_green_btn);
}
};
Normal:
rbl_blinkNormal= new Runnable() {
#Override
public void run() {
btn_richtig.setBackgroundResource(R.drawable.color_black_btn);
}
};
It works fine but like this Im calling the postDelayed() every 250ms. May this impact my application performance and is there any better way to do this?

You can animate your button once you set its color to say GREEN. I mean,
if(answerTrue){
// Set the color of the button to GREEN once.
// Next, animate its visibility with the set color - which is GREEN as follows:
Animation anim = new AlphaAnimation(0.0f, 1.0f);
anim.setDuration(50); //You can manage the blinking time with this parameter
anim.setStartOffset(20);
anim.setRepeatMode(Animation.REVERSE);
anim.setRepeatCount(Animation.INFINITE);
button.startAnimation(anim);
}
Similarly, you can animate the other button and stop animation when you feel like.
Source: Blinking Text in android view

If you want to blink the image only, here is an example.
Button bt_notes = (Button) findViewById(R.id.bt_notes);
int bt_notes_blink = 0;
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
runOnUiThread(new Runnable() {
#Override
public void run() {
int DrawableImage[] = {R.drawable.picto_keys, R.drawable.picto_blank};
Resources res = getApplicationContext().getResources();
bt_notes.setCompoundDrawablesWithIntrinsicBounds(null, null, null, res.getDrawable(DrawableImage[bt_notes_blink]));
bt_notes_blink++;
if (bt_notes_blink == 2) { bt_notes_blink = 0; }
handler.postDelayed(this, 500);
}
});
}
}, 0);

Related

ViewPropertyAnimator messing with view layout position

I created a button, set the position using top and left margin and added to the layout. If i just do this the buttons sits there in the right location.
Now I need to add a translation animation, and I am using viewPropertyAnimator.
Unfortunately this voids the initial button position, making the animation start from (0, 0).
Following is the code I wrote.
final Button bonus_button = new Button(this);
int bonus_y_start, bonus_x_start, bonus_y_end, bonus_x_end;
bonus_x_start = random.nextInt(2) == 1 ? layout_width + button_size : -1 * button_size;
bonus_y_start = random.nextInt(layout_height + 2 * button_size) - button_size;
if (bonus_x_start < 0)
bonus_x_end = layout_width + button_size;
else
bonus_x_end = -1 * button_size;
bonus_y_end = random.nextInt(layout_height + button_size) - button_size;
RelativeLayout.LayoutParams bonus_l = new RelativeLayout.LayoutParams(button_size, button_size);
bonus_l.leftMargin = bonus_x_start;
bonus_l.topMargin = bonus_y_start;
bonus_button.setLayoutParams(bonus_l);
bonus_button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
mHandler.sendEmptyMessage(MSG_PAUSE_TIMER);
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
mHandler.sendEmptyMessage(MSG_RESUME_TIMER);
}
}, 2000);
}
});
bonus_button.bringToFront();
ViewPropertyAnimator animator = bonus_button.animate().x(bonus_x_end).y(bonus_y_end);
animator.setDuration(2000);
animator.withEndAction(new Runnable() {
#Override
public void run() {
layout.removeView(bonus_button);
}
});
layout.addView(bonus_button);
Anybody has any idea on where I'm doing wrong?
Use bonus_l.setX(bonus_x_start) and bonus_l.setY(bonus_x_start) instead of margins

While loop: Change Background color

I am trying to create a small animation which changes smoothly the background color. My problem is that it only shows the last value (100, that means it directly goes to a red background). I don't know why my created while-loop doesn't actualize every value (so that it would show a smoothly color animation)
New code (which almost works, but Idk how to stop the animation)
imageButton_info.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v){
final Handler handler = new Handler();
Runnable ChangeBackgroundRunnable = new Runnable() {
#Override
public void run() {
number++;
float[] hsvColor = {0, 1, 1};
hsvColor[0] = 360f * number / 100;
color.setBackgroundColor(Color.HSVToColor(hsvColor));
handler.postDelayed(this, 80);
if (number >=100)
number = 1;
}
};
number = 0;
handler.removeCallbacks(ChangeBackgroundRunnable);
handler.postDelayed(ChangeBackgroundRunnable, 0);
}
});
Code:
public void onClick(View v){
try {
while (number<=100) {
number=number+1;
float[] hsvColor = {0, 1, 1};
hsvColor[0] = 360f * number / 100;
color.setBackgroundColor(Color.HSVToColor(hsvColor));
Thread.sleep(10);
}
}catch(Exception e){
//New exception
Log.e("Camera Error!",e.getMessage());
}
Thank you for your answer in advance...
When you change something in the UI, it doesn't happen immediately. Instead, it posts a message to the Looper on the UI thread. When control returns to the looper (when you're done with whatever function the framework called), it will process all the messages on the Looper, until it eventually processes the redraw request. Then it will draw. So if you're looping in onClick, you will not get any updates to the screen. If you want something to happen in 10ms, post a delayed message to a Handler and update the UI in that thread.
Side note: NEVER EVER sleep on the UI thread. The reason is that no input or draw commands can be processed if you're not returning control to the Looper. So your app becomes unresponsive. If you do it long enough, it can even cause the framework to kill your app for being unresponsive.
A better way to do this would be to use an Android animation. I stole the code for this from here
int colorFrom = getResources().getColor(R.color.red);
int colorTo = getResources().getColor(R.color.blue);
ValueAnimator colorAnimation = ValueAnimator.ofObject(new ArgbEvaluator(), colorFrom, colorTo);
colorAnimation.setDuration(250); // milliseconds
colorAnimation.addUpdateListener(new AnimatorUpdateListener() {
#Override
public void onAnimationUpdate(ValueAnimator animator) {
textView.setBackgroundColor((int) animator.getAnimatedValue());
}
});
colorAnimation.start();
Wrapped the answers posted by #gabe-sechan and #jesse-buss
ValueAnimator support from devices SDK above HONEYCOMB. So below that SDK level we'll use #gabe-sechan suggestion. Check the below code.
private void executeBackgroundChange() {
// Handler and runnable to run the animation in devices sdk below honeycomb.
mHandler = new Handler();
mChangeBackgroundRunnable = new Runnable() {
#Override
public void run() {
number++;
float[] hsvColor = {0, 1, 1};
hsvColor[0] = 360f * number / 100;
mContainer.setBackgroundColor(Color.HSVToColor(hsvColor));
mHandler.postDelayed(this, 500);
if (number == 100)
number = 0;
}
};
number = 0;
mHandler.removeCallbacks(mChangeBackgroundRunnable);
mHandler.postDelayed(mChangeBackgroundRunnable, 0);
}
#TargetApi(Build.VERSION_CODES.HONEYCOMB)
private void executeBackgroundChangeUsingValueAnimator() {
colorAnimation = ValueAnimator.ofObject(new ArgbEvaluator(), getResources().getColor(R.color.red), getResources().getColor(R.color.blue));
colorAnimation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
#Override
public void onAnimationUpdate(final ValueAnimator animator) {
mContainer.setBackgroundColor((Integer) animator.getAnimatedValue());
}
});
colorAnimation.setRepeatCount(ValueAnimator.INFINITE);
colorAnimation.setDuration(10 * 1000);
colorAnimation.start();
}
Add the below method and to stop the animation on click of something call the below method.
private void stopBackgroundChangeAnimation() {
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB) {
if (colorAnimation != null && colorAnimation.isRunning())
colorAnimation.end();
} else {
if (mHandler != null && mChangeBackgroundRunnable != null)
mHandler.removeCallbacks(mChangeBackgroundRunnable);
}
}
Check the github project for reference.
Try to use runOnUiThread
public void onCreate(Bundle savedInstanceState) {
res = getResources();
super.onCreate(savedInstanceState);
setContentView(R.layout.xyz);//**Works**/
handler.postDelayed(runnable, 10);
}
private Runnable runnable = new Runnable() {
public void run() {
runOnUiThread(new Runnable() {
public void run()
{
try {
while (number<=100) {
number=number+1;
float[] hsvColor = {0, 1, 1};
hsvColor[0] = 360f * number / 100;
color.setBackgroundColor(Color.HSVToColor(hsvColor));
}
}catch(Exception e){
//New exception
}
}
});
}
}

How to make a proper move in/out animation?

In onViewCreate I set the view behind the screen:
holderMenus.post(new Runnable() {
#Override public void run() {
if (holderMenus != null) {
if (DeviceType.INSTANCE.tablet) {
holderMenus.animate().translationY(-holderMenus.getHeight());
} else {
holderMenus.animate().translationY(holderMenus.getHeight());
}
}
}
});
Then, when I want to move the view in:
holderMenus.animate().translationY(0).setDuration(300);
That works well; the view slides in. Next I want to move the view off the screen:
if (DeviceType.INSTANCE.tablet) {
holderMenus.animate().translationY(-holderMenus.getHeight()).setDuration(300);
} else {
holderMenus.animate().translationY(holderMenus.getHeight()).setDuration(300);
}
But instead of sliding, the view disappears, as if I had set the property to .setVisibility(View.GONE);
How can I make it slide instead?
I have made a custom action button that slides from below the screen and slides back under the screen when listview is scrolled.
Hides:
TranslateAnimation anim = new TranslateAnimation(0, 0, 0, 500);
anim.setDuration(300l);
anim.setFillAfter(true);
layout.startAnimation(anim); //layout is the layout with the button
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
layout.clearAnimation();
layout.setVisibility(View.GONE);
}
}, 300l);
Shows:
Handler h = new Handler();
h.postDelayed(new Runnable() {
#Override
public void run() {
try {
layout.setVisibility(View.VISIBLE);
TranslateAnimation anim = new TranslateAnimation(0, 0, 500, 0);
anim.setDuration(300l);
anim.setFillAfter(true);
layout.startAnimation(anim);
} catch (Exception e) {
e.printStackTrace();
}
}
}, 500l);
I guess that slide out animation is not starting from the point that you think it is. It probably "animates" in the same position off the screen.
You might want to try ObjectAnimator, where you can specify both starting and ending points for your animation using ofFloat method for example.

How would i make imageView rolling in from bottom left corner to the bottom right corner?

Does anyone know how would i do this? And imageView should come from outside of the activity.
Here is the code:
rollingImageView = (ImageView) findViewById(R.id.imageView1);
AnimationSet rollingIn = new AnimationSet(true);
Animation moving = new TranslateAnimation(Animation.RELATIVE_TO_PARENT,-1f,Animation.RELATIVE_TO_PARENT,0,Animation.RELATIVE_TO_PARENT, 0, Animation.RELATIVE_TO_PARENT, 0);
moving.setDuration(5000);
rollingIn.addAnimation(moving);
Animation rotating = new RotateAnimation(0, 720, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
rotating.setDuration(5000);
rollingIn.addAnimation(rotating);
rollingImageView.startAnimation(rollingIn);
Assuming you have your imageview set to the bottom left down, (this will only help you go from left to right)
In your activity file...
public void callthismethodtostartrolling(){
final Thread myThread = new Thread(new Runnable()
{
#Override
public void run()
{
while (!<imageviewInRightCorner>) {//<<define this yourself
try {
Thread.sleep(4);
runOnUiThread(new Runnable()
{
#Override
public void run() {
rollingImageView.setX((float) (rollingImageView.getX() + 5));
}
});
} catch (InterruptedException e) {
// this should not happen
}
}
}
});
myThread.start
}
PROS
I think it gives the effect you want.
CONS
Ive tried this before, it works, but you cant interrupt the Thread inside the Thread if you ever need to do so. The link to the original problem/con of this is here,if you would like to help Dusan and I ._.
ALTERNATIVE
final Thread myThread = new Thread(new Runnable()
{
#Override
public void run()
{
while (!<imageviewInRightCorner>) {//<<define this yourself
try {
Thread.sleep(4);
runOnUiThread(new Runnable()
{
#Override
public void run() {
rollingImageView.setX((float) (rollingImageView.getX() + 5));
}
});
} catch (InterruptedException e) {
// this should not happen
}
}
}
});
Using myThread.start anywhere in your code to activate your sliding imageview awesomeness.
PROS
Alternative to first option with a different con to suit your need
*able to use myThread.interrupt within Thread
CONS
Cant call the Thread more than once per launch :/ the reason why is all in here
potential while condition explained(as requested by asker)...

How to animate multiple objects one by one after some intervals android

How to animate multiple objects one by one after some intervals android
i am using this code for animation
for (int y = 0; y < 10; y++) {
runOnUiThread(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
Toast.makeText(ProjectFirstActivity.this, y + "",
Toast.LENGTH_SHORT).show();
ObjectAnimator oa = ObjectAnimator.ofFloat(myimageview[y],
"translationY", 0, -200);
oa.setDuration(1000);
oa.start();
}
});
}
but it is animating all in one go but i want one by one animation of my imageview please help
No need to use Threads and Handlers. Instead of that use,
objectAnimator.setStartDelay(delay);
Using that you can stop that animation for the respective 'delay'
Try this code..
int delay = 1000;
for (int y = 0; y < 10; y++) {
Toast.makeText(ProjectFirstActivity.this, y + "",
Toast.LENGTH_SHORT).show();
ObjectAnimator oa = ObjectAnimator.ofFloat(myimageview[y],
"translationY", 0, -200);
oa.setDuration(1000);
oa.setStartDelay(delay);
oa.start();
delay = delay+1000;
}
You can use for loop to generate AnimatorSet and then play them sequentially using set.playSequentially(yourAnimatorSetListHere);
I haven't used list in below mentioned snippet.
AnimatorSet decSet = new AnimatorSet();
decSet.playTogether(
ObjectAnimator.ofArgb(mTextSlidetoCancel, "visibility", View.GONE, View.VISIBLE),
ObjectAnimator.ofArgb(mBtnMicActive, "visibility", View.GONE, View.VISIBLE),
ObjectAnimator.ofArgb(mChronometer, "visibility", View.GONE, View.VISIBLE));
decSet.setDuration(125);
AnimatorSet decSet2 = new AnimatorSet();
decSet2.playTogether(
ObjectAnimator.ofArgb(mBtnAttach, "visibility", View.VISIBLE, View.GONE),
ObjectAnimator.ofArgb(mBtnEmoji, "visibility", View.VISIBLE, View.GONE),
ObjectAnimator.ofArgb(mEditTExt, "visibility", View.VISIBLE, View.GONE)
);
decSet2.setDuration(125);
AnimatorSet set = new AnimatorSet();
set.playSequentially(decSet2,decSet);
set.start();
Try out this way!
public Integer[] Imgid = {R.drawable.anim2, R.drawable.anim3,
R.drawable.anim4, R.drawable.anim5}; // your image array.
Animation anim;
Handler handler;
ImageView iv;
int count;
Runnable galleryAnimRunnable;
Inside onCreate
iv= (ImageView)findViewById(R.id.imagetype);
handler = new Handler();
galleryAnimRunnable = new Runnable() {
public void run() {
if(count==Imgid.length){
//do any action
}
else{
anim = AnimationUtils.loadAnimation(AnimationScreen.this, R.anim.fade_out); // load your desire animation.
iv.setBackgroundResource(Imgid[count]);
iv.setAnimation(anim);
count++;
handler.postDelayed(galleryAnimRunnable, 300); //set your desire delay time.
}
}
};
Your sleep call isn't helping because when one posted UI job goes to sleep, then next one starts and goes to sleep immediately following that, and so on. Then the first job wakes up and runs, followed closely by the second job awakening and running, etc.
If you want the sleep to help you need to wait before posting each job, which could be as simple as something like the following:
for (int y = 0; y < 10; y++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(ProjectFirstActivity.this, y + "",
Toast.LENGTH_SHORT).show();
ObjectAnimator oa = ObjectAnimator.ofFloat(myimageview[y],
"translationY", 0, -200);
oa.setDuration(1000);
oa.start();
}
});
}
EDIT: Although the above explains why you were having problems, I would recommend going with something like the answer posted by Jgdsh Seerm using setStartDelay().
Try this way!
ImageView image1;
public int currentimageindex1=0;
Timer timer;
TimerTask task;
private Animation animation1;
private Animation animation2;
int img[] = {R.drawable.aa, R.drawable.bb,
R.drawable.cc,R.drawable.dd,R.drawable.ee,R.drawable.ff,R.drawable.gg,
R.drawable.hh};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final Handler mHandler = new Handler();
// Create runnable for posting
final Runnable mUpdateResults = new Runnable() {
public void run() {
AnimateandSlideShow();
}
};
int delay = 1000; // delay for 1 sec.
int period = 4000; // repeat every 4 sec.
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
mHandler.post(mUpdateResults);
}
}, delay, period);
}
public void onClick(View v) {
finish();
android.os.Process.killProcess(android.os.Process.myPid());
}
/**
* Helper method to start the animation on the splash screen
*/
private void AnimateandSlideShow() {
image1 = (ImageView)findViewById(R.id.imageView1);
image1.setImageResource(img[currentimageindex1%img.length]);
currentimageindex1++;
}

Categories

Resources