How do you animate the change of background color of a view on Android?
For example:
I have a view with a red background color. The background color of the view changes to blue. How can I do a smooth transition between colors?
If this can't be done with views, an alternative will be welcome.
On Android 4.4 (API level 19) and higher, you can use the transition framework to create animations when you swap the layout within the current activity or fragment. All you need to do is specify the starting and ending layout, and what type of animation you want to use.
Android's transition framework allows you to animate all kinds of motion in your UI by simply providing the starting layout and the ending layout.
You can use new Property Animation Api for color animation:
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();
For backward compatibility with Android 2.x use Nine Old Androids library from Jake Wharton.
The getColor
method was deprecated in Android M, so you have two choices:
If you use the support library, you need to replace the getColor
calls with:
ContextCompat.getColor(this, R.color.red);
if you don't use the support library, you need to replace the getColor
calls with:
getColor(R.color.red);
I ended up figuring out a (pretty good) solution for this problem!
You can use a TransitionDrawable to accomplish this. For example, in an XML file in the drawable folder you could write something like:
<?xml version="1.0" encoding="UTF-8"?>
<transition xmlns:android="http://schemas.android.com/apk/res/android">
<!-- The drawables used here can be solid colors, gradients, shapes, images, etc. -->
<item android:drawable="@drawable/original_state" />
<item android:drawable="@drawable/new_state" />
</transition>
Then, in your XML for the actual View you would reference this TransitionDrawable in the android:background
attribute.
At this point you can initiate the transition in your code on-command by doing:
TransitionDrawable transition = (TransitionDrawable) viewObj.getBackground();
transition.startTransition(transitionTime);
Or run the transition in reverse by calling:
transition.reverseTransition(transitionTime);
See Roman's answer for another solution using the Property Animation API, which wasn't available at the time this answer was originally posted.
Depending on how your view gets its background color and how you get your target color there are several different ways to do this.
The first two uses the Android Property Animation framework.
Use a Object Animator if:
argb
value in a xml file.view.setBackgroundColor()
The object animator works by calling view.setBackgroundColor
which replaces the defined drawable unless is it an instance of a ColorDrawable
, which it rarely is. This means that any extra background properties from a drawable like stroke or corners will be removed.
Use a Value Animator if:
Use a Transition drawable if:
I have had some performance issues with Transition drawables that runs while I am opening a DrawerLayout that I haven't been able to solve, so if you encounter any unexpected stuttering you might have run into the same bug as I have.
You will have to modify the Value Animator example if you want to use a StateLists drawable or a LayerLists drawable, otherwise it will crash on the final GradientDrawable background = (GradientDrawable) view.getBackground();
line.
Object Animator:
View definition:
<View
android:background="#FFFF0000"
android:layout_width="50dp"
android:layout_height="50dp"/>
Create and use a ObjectAnimator
like this.
final ObjectAnimator backgroundColorAnimator = ObjectAnimator.ofObject(view,
"backgroundColor",
new ArgbEvaluator(),
0xFFFFFFFF,
0xff78c5f9);
backgroundColorAnimator.setDuration(300);
backgroundColorAnimator.start();
You can also load the animation definition from a xml using a AnimatorInflater like XMight does in Android objectAnimator animate backgroundColor of Layout
Value Animator:
View definition:
<View
android:background="@drawable/example"
android:layout_width="50dp"
android:layout_height="50dp"/>
Drawable definition:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#FFFFFF"/>
<stroke
android:color="#edf0f6"
android:width="1dp"/>
<corners android:radius="3dp"/>
</shape>
Create and use a ValueAnimator like this:
final ValueAnimator valueAnimator = ValueAnimator.ofObject(new ArgbEvaluator(),
0xFFFFFFFF,
0xff78c5f9);
final GradientDrawable background = (GradientDrawable) view.getBackground();
currentAnimation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(final ValueAnimator animator) {
background.setColor((Integer) animator.getAnimatedValue());
}
});
currentAnimation.setDuration(300);
currentAnimation.start();
Transition drawable:
View definition:
<View
android:background="@drawable/example"
android:layout_width="50dp"
android:layout_height="50dp"/>
Drawable definition:
<?xml version="1.0" encoding="utf-8"?>
<transition xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape>
<solid android:color="#FFFFFF"/>
<stroke
android:color="#edf0f6"
android:width="1dp"/>
<corners android:radius="3dp"/>
</shape>
</item>
<item>
<shape>
<solid android:color="#78c5f9"/>
<stroke
android:color="#68aff4"
android:width="1dp"/>
<corners android:radius="3dp"/>
</shape>
</item>
</transition>
Use the TransitionDrawable like this:
final TransitionDrawable background = (TransitionDrawable) view.getBackground();
background.startTransition(300);
You can reverse the animations by calling .reverse()
on the animation instance.
There are some other ways to do animations but these three is probably the most common. I generally use a ValueAnimator.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With