我遇到了类似的问题。我尝试使用 Blueberry 建议的层列表方法,但是一旦我为徽标添加了高分辨率资产,该解决方案就不再有效。图层列表中的位图有一个错误:它会放大较小的图像以适应空间,但不会缩小较大的图像。因此,只要您可以使用放大后看起来有颗粒/像素化的微小图像,图层列表就可以正常工作。
为了解决这个问题并获得居中的高分辨率徽标,我从工具栏中完全删除了android:background 属性,将android:background="?attr/colorPrimary" 添加到我的AppBarLayout 父级,然后将这个糟糕的代码扔到我的活动的onCreate 中方法:
final Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
ActionBar ab = getSupportActionBar();
if (ab != null && toolbar != null)
{
// Hide the title text.
ab.setDisplayShowTitleEnabled(false);
// Convert and show the logo.
toolbar.addOnLayoutChangeListener(new View.OnLayoutChangeListener()
{
@Override
public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom)
{
ActionBar ab = getSupportActionBar();
if (ab != null)
{
Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.drawable.logo);
Bitmap bmp2 = Bitmap.createBitmap(toolbar.getWidth(), toolbar.getHeight(), bmp.getConfig());
Bitmap bmp3 = Bitmap.createScaledBitmap(bmp, bmp.getWidth() * toolbar.getHeight() / bmp.getHeight(), toolbar.getHeight(), true);
Canvas canvas = new Canvas(bmp2);
canvas.drawBitmap(bmp3, (toolbar.getWidth() / 2) - (bmp3.getWidth() / 2), 0, null);
BitmapDrawable background = new BitmapDrawable(getResources(), bmp2);
ab.setBackgroundDrawable(background);
}
}
});
}
它的工作原理是创建一个工具栏大小的画布和一个比例缩放版本的徽标,将新调整大小的徽标绘制到中心的画布上,最后将正在绘制的位图设置为动作的背景吧。
从好的方面来说,这种方法可以让您完全控制放置、大小等。不限于您可以在 XML 中执行的任何操作。这很糟糕,因为每当工具栏布局发生变化时都会定期调用它,这意味着会影响性能。但是,当您的设计团队(并不关心 Material Design 的第一件事)要求您拥有一个背景徽标并浪费五个小时寻找上述解决方案时,性能就不再重要了 - 您只希望该死的东西能够工作。上面的代码充满了绝望的味道。
我会让在 Android 开发方面比我更有能力的人指出“我做错了”并修复上述代码存在的任何性能问题/错误。它不会改变图层列表位图已损坏的事实,这是一个 hack(不应该存在)来修复 Android 中的愚蠢错误(也不应该存在)。