I used a Drawable as background of the Action Bar. In this way you can use different MenuItem on left and/or right and the logo will be everytime centered.
I needed to animate also the logo when it has been loaded through Picasso, and this is the result:

I've used a LayerDrawable for animating just one Drawable (a layer) into it.
This is the code, maybe could be useful for someone:
getSupportActionBar().show();
getSupportActionBar().setDisplayShowCustomEnabled(true);
getSupportActionBar().setDisplayShowTitleEnabled(false);
showActionBarLogo(this, true);
And this is the showActionBarLogo function for showing and hiding the Action bar logo:
public void showActionBarLogo(final Activity activity, boolean show)
{
if (show)
{
// Calculate Action bar height
int actionBarHeight = 200;
TypedValue tv = new TypedValue();
if (activity.getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, true))
{
actionBarHeight = TypedValue.complexToDimensionPixelSize(tv.data,activity.getResources().getDisplayMetrics());
}
// Using action bar background drawable
logoTarget = new Target() {
@Override
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
Drawable[] layers = new Drawable[2];
layers[0] = new ColorDrawable(Color.RED); // Background color of Action bar
BitmapDrawable bd = new BitmapDrawable(activity.getResources(), bitmap);
bd.setGravity(Gravity.CENTER);
Drawable drawLogo = bd;
layers[1] = drawLogo; // Bitmap logo of Action bar (loaded from Picasso)
LayerDrawable layerDrawable = new LayerDrawable(layers);
layers[1].setAlpha(0);
((AppCompatActivity) activity).getSupportActionBar().setBackgroundDrawable(layerDrawable);
ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(layers[1], PropertyValuesHolder.ofInt("alpha", 255));
animator.setTarget(layers[1]);
animator.setDuration(2000);
animator.start();
}
@Override public void onBitmapFailed(Drawable errorDrawable) { }
@Override public void onPrepareLoad(Drawable placeHolderDrawable) { }
};
Picasso.with(activity).load("https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_120x44dp.png").resize(0, actionBarHeight).into(logoTarget);
} else {
((AppCompatActivity) activity).getSupportActionBar().setBackgroundDrawable(new ColorDrawable(Color.RED));
}
}
I've created a drawable for the Action Bar with:
- a layer (0) which is a background color and
- a layer (1) with the
logo in the middle of it (with fade animation)
I load the logo with Picasso and I like to animate it when has been loaded (bitmap onBitmapLoaded callback).
Bear in mind to declare Picasso Target out of showActionBarLogo function to avoid garbage issue on loading images:
private Target logoTarget;
If you don't need the Picasso loading, you can use only the code into onBitmapLoaded
function and using a Drawable instead of the bitmap variable.
Same thing if you don't need the fade animation. You can remove the layers[1].setAlpha(0);
line and also all the ObjectAnimator
lines.
I've tested it from Android 4.4 (api 19) to 8.1 (api 27) and it works great!
I hope this could help!