Android Tip: Synchronously Animating Toolbar, TabLayout, and StatusBar Background Colors

    As you can see on Google Play application, when you change selected tab on the main screen (which has 2 tabs: App & Game and Books), the TabLayout, Toolbar and Status bar background color are also changed with an animation. This effect is look like this:

    By using TabLayout widget of Design Support Library, we can make this effect easily.
    Basically, within the onTabSelected() method of my TabLayout.OnTabSelectedListener implementation, I wanted to animate from the current color to the new tab’s corresponding color, ensuring that all views are animating simultaneously. Call this interface through addOnTabSelectedListener():
tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
            @Override
            public void onTabSelected(TabLayout.Tab tab) {
                //Add more code in this method later
            }

            @Override
            public void onTabUnselected(TabLayout.Tab tab) {

            }

            @Override
            public void onTabReselected(TabLayout.Tab tab) {

            }
    To do this, I chose to use the ValueAnimator which allows you to iterate over the difference of two values over a timed interval. I also used an ArgbEvaluator for the ValueAnimator’s evaluator to handle the calculation of each animation step between the two ARGB colors:
int colorFrom = ((ColorDrawable) toolbar.getBackground()).getColor();
int colorTo = getColorForTab(tab.getPosition());
    We use the toolbar’s current background color as the starting color of the animation, and determine the color to animate to based on the newly selected tab.
    Now the ValueAnimator can be used to inform us of what color to use during each animation iteration:
colorAnimation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                    @Override
                    public void onAnimationUpdate(ValueAnimator animator) {
                        int color = (int) animator.getAnimatedValue();

                        toolbar.setBackgroundColor(color);
                        tabLayout.setBackgroundColor(color);

                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                            getWindow().setStatusBarColor(color);
                        }
                    }

                });
colorAnimation.start();
    In order to setting the animation duration, you can use this code before call colorAnimation.start():
colorAnimation.setDuration(1000); //time in milliseconds
Finally, we have full code for this main activity:
MainActivity.java
package info.devexchanges.synchronouslycolor;

import android.animation.ArgbEvaluator;
import android.animation.ValueAnimator;
import android.graphics.drawable.ColorDrawable;
import android.os.Build;
import android.os.Bundle;
import android.support.design.widget.TabLayout;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;

public class MainActivity extends AppCompatActivity {

    private TabLayout tabLayout;
    private Toolbar toolbar;
    private String[] colors = {"Red", "Blue", "Green", "Yellow", "Gray"};

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        tabLayout = (TabLayout) findViewById(R.id.tab_layout);
        toolbar = (Toolbar) findViewById(R.id.toolbar);

        setSupportActionBar(toolbar);

        for (String color : colors) {
            tabLayout.addTab(tabLayout.newTab().setText(color));
        }

        tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
        tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
            @Override
            public void onTabSelected(TabLayout.Tab tab) {
                int colorFrom = ((ColorDrawable) toolbar.getBackground()).getColor();
                int colorTo = getColorForTab(tab.getPosition());

                ValueAnimator colorAnimation = ValueAnimator.ofObject(new ArgbEvaluator(), colorFrom, colorTo);
                colorAnimation.setDuration(1000);
                colorAnimation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                    @Override
                    public void onAnimationUpdate(ValueAnimator animator) {
                        int color = (int) animator.getAnimatedValue();

                        toolbar.setBackgroundColor(color);
                        tabLayout.setBackgroundColor(color);

                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                            getWindow().setStatusBarColor(color);
                        }
                    }

                });
                colorAnimation.start();
                toolbar.setTitle(colors[tab.getPosition()].toUpperCase());
            }

            @Override
            public void onTabUnselected(TabLayout.Tab tab) {

            }

            @Override
            public void onTabReselected(TabLayout.Tab tab) {

            }
        });
    }

    public int getColorForTab(int position) {
        if (position == 0) return ContextCompat.getColor(this, R.color.colorPrimary);
        else if (position == 1) return ContextCompat.getColor(this, R.color.blue);
        else if (position == 2) return ContextCompat.getColor(this, R.color.green);
        else if (position == 3) return ContextCompat.getColor(this, R.color.yellow);
        else return ContextCompat.getColor(this, R.color.gray);
    }
}
    And that’s all there is to it - we now have a good animation, make our app look more smoothly and prettier! This is full screen output:

    References:

Share


Previous post
« Prev Post
Next post
Next Post »