I'm writing a simple app that implements a material design compliant nav drawer as described by this Stack post: https://stackoverflow.com/a/27153313/1621380
The ScrimInsetsFrameLayout
works great and everything is dandy until I attempt to programmatically change the color of the status bar. My app uses the Palette API to change the toolbar and status bar color dynamically.
I'm using the property animation api to animate the toolbar and it works great! but I try to do the same animation on the statusbar and it doesn't seem to want to animate. Here's an example
Here is the code for my animator:
public static void fadeStatusBar(final DrawerLayout layout, Integer from, Integer to) {
if(android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
ValueAnimator colorAnimation = ValueAnimator.ofObject(new ArgbEvaluator(), from, to);
colorAnimation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animator) {
layout.setStatusBarBackgroundColor((Integer) animator.getAnimatedValue());
}
});
colorAnimation.start();
}
}
Note: That same code is fading the toolbar, so its proven to work.
My question is; does anyone know of a way to get a smooth transition when using DrawerLayout.setStatusBarBackgorundColour()
?
Note: I have used the Window method window.setStatusBarColor()
method, and it animates fine but breaks the "transparent statusbar" when the NavDrawer is pulled in.
As advised @adneal's comment on my original question the answer was to invalidate the view during the animation.
DrawerLayout calculates the top inset and draws the status bar background itself. So, you just need to make a call to View.invalidate to force it to redraw while the animation is being updated. @adneal
I've updated my code to this
ValueAnimator colorAnimation = ValueAnimator.ofArgb(from, to);
colorAnimation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animator) {
layout.invalidate();
layout.setStatusBarBackgroundColor((Integer) animator.getAnimatedValue());
}
});
colorAnimation.start();
For anyone wondering why this worked, I found this stack post enlightening: When it's necessary to execute invalidate() on a View?
you can do this Easily like below:
1 - set your statusbar color to transparent by using this:
<item name="colorPrimaryDark">@android:color/transparent</item>
2 - define application's view to change it background:
View root = *A_view_on_the_activity*.getRootView();
3 - then add this function to your project:
private void color_change(final View view,int from_color,int to_color){
final float[] from = new float[3],
to = new float[3];
String hexColor_from = String.format("#%06X", (0xFFFFFF & from_color));
String hexColor_to = String.format("#%06X", (0xFFFFFF & to_color));
Color.colorToHSV(Color.parseColor(hexColor_from), from); // from
Color.colorToHSV(Color.parseColor(hexColor_to), to); // to
ValueAnimator anim = ValueAnimator.ofFloat(0, 1); // animate from 0 to 1
anim.setDuration(600); // for 300 ms
final float[] hsv = new float[3]; // transition color
anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener(){
@Override public void onAnimationUpdate(ValueAnimator animation) {
// Transition along each axis of HSV (hue, saturation, value)
hsv[0] = from[0] + (to[0] - from[0])*animation.getAnimatedFraction();
hsv[1] = from[1] + (to[1] - from[1])*animation.getAnimatedFraction();
hsv[2] = from[2] + (to[2] - from[2])*animation.getAnimatedFraction();
view.setBackgroundColor(Color.HSVToColor(hsv));
}
});
anim.start();
}
4 - and then change the hole application's background color animation by using the function that Written above:
color_change(root, from_color, to_color);
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