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
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: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);
}
}
References: