【问题标题】:Transparent adaptive icon background透明自适应图标背景
【发布时间】:2018-05-23 04:58:14
【问题描述】:

所以我已经在这个应用程序上工作了几个星期,并开始构建图标。我有 Android Studio 3.0.1,它们似乎改变了图像资产的制作方式,现在它们具有自适应图标。我为我的应用制作了一个透明背景的图标。以前,我只需将形状更改为“无”,就不会生成背景。但现在这不是一个选择,除非我去“遗产”,这是无用的。背景颜色似乎不支持透明度。即使在ic_launcher.xml 中我将背景设置为透明颜色,但图标仍然以黑色背景显示。

这是我的ic_lancher.xml

<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
    <background android:drawable="@color/transparent"/>
    <foreground android:drawable="@mipmap/ic_launcher_foreground"/>
</adaptive-icon>

和ic_launcher_round.xml 是一样的。 @color/transparent 位是这样的:

<color name="transparent">#00000000</color>

【问题讨论】:

标签: android


【解决方案1】:

TL;DR自适应图标不能有透明背景

透明背景将是不透明的黑色。

根据Android 8.0框架的源码,&lt;background&gt;层本来就是不透明的;如问题中所述,框架用不透明的黑色填充背景。

该框架有一个类AdaptiveIconDrawable,用于绘制自适应启动器图标。 https://developer.android.com/reference/android/graphics/drawable/AdaptiveIconDrawable.html
&lt;adaptive-icon&gt; 元素创建了它的一个实例:

除了动态创建之外,还可以使用&lt;adaptive-icon&gt; 标签通过 XML 膨胀创建此类。

AdaptiveIconDrawable.java 中方法drawThe source code 是:

@Override
public void draw(Canvas canvas) {
    if (mLayersBitmap == null) {
        return;
    }
    if (mLayersShader == null) {
        mCanvas.setBitmap(mLayersBitmap);
        mCanvas.drawColor(Color.BLACK);
        for (int i = 0; i < mLayerState.N_CHILDREN; i++) {
            if (mLayerState.mChildren[i] == null) {
                continue;
            }
            final Drawable dr = mLayerState.mChildren[i].mDrawable;
            if (dr != null) {
                dr.draw(mCanvas);
            }
        }
        mLayersShader = new BitmapShader(mLayersBitmap, TileMode.CLAMP, TileMode.CLAMP);
        mPaint.setShader(mLayersShader);
    }
    if (mMaskBitmap != null) {
        Rect bounds = getBounds();
        canvas.drawBitmap(mMaskBitmap, bounds.left, bounds.top, mPaint);
    }
}

简而言之,Canvas 实例接收要绘制的位图,最初它用黑色填充位图。然后前景可绘制对象和背景可绘制对象完成工作:

mCanvas.setBitmap(mLayersBitmap); // reset
mCanvas.drawColor(Color.BLACK);   // fill
for (int i = 0; i < mLayerState.N_CHILDREN; i++) { // two layers
    ...
    final Drawable dr = mLayerState.mChildren[i].mDrawable;
    ...
        dr.draw(mCanvas); // draw
    ...
}

Color.BLACK 是不透明的:

0xff000000

drawColor 方法用它填充位图,使用SRC_OVER 模式:

使用 srcover porterduff 模式,用指定的颜色填充整个画布的位图(仅限于当前剪辑)。

因此,即使您将背景设置为透明色,背景也将始终不透明,如下面的屏幕截图所示(来自my answer 的类似问题)。

【讨论】:

  • 如何让它变白?
  • 如果您在“res/values/color.xml”中为@color/transparent 设置&lt;color name="transparent"&gt;#ffffffff&lt;/color&gt;,它将是白色的,如问题中所示。
  • @Dika 一些启动器应用程序,例如Pixel Launcher 会将启动器图标的背景颜色更改为白色,正如我在my answer to a similar question 的“更新#2”部分中所写。
  • 为什么Android要模仿iOS,去掉自己的优点?!
【解决方案2】:

有史以来最简单的解决方案:

  1. 假设你有一个透明背景的PNG文件(最好是正方形比例),我们称之为“app_icon.png”,把它放在你的drawable文件夹中 P.S:大小不重要,重要的是平方。

  2. 转到 AndroidManifest.xml,在您的主应用程序标签中,检查

    android:icon="@mipmap/app_icon"

并将其更改为

android:icon="@drawable/app_icon"
  1. 现在删除所有“mipmap”文件夹,因为您不需要它们。

为什么会这样:这告诉 android 直接使用文件夹中的可绘制对象作为图标,而无需通过 mipmap XML 文件的障碍。

恭喜,现在您将拥有一个透明背景的徽标。

【讨论】:

  • 这是我正在寻找的真正答案。谢谢艾莉亚丹尼斯。你节省了我的时间。
  • 请有人解释一下为什么这个答案在这里,用两行解释了如何解决问题。
【解决方案3】:

您说旧图标“无用”,但唯一合乎逻辑的解决方案是使用旧图标。如果您根本不创建自适应图标,Android 8.0 及更高版本将不得不使用旧图标。此外,具有透明背景的自适应图标是一个矛盾的概念,因为自适应图标的主要特点是前景包含在 OEM 确定的形状内。但如果背景是透明的,怎么会有任何形状呢?你可能会问如何做一个圆。

【讨论】:

    【解决方案4】:

    使用带有透明 XML 背景层的 Android Studio 生成启动器图标,然后从 res/mipmap-anydpi-v26(黑色背景的图标)中删除 ic_launcher.xmlic_launcher_round.xml。然后,Android 将不得不回退到具有透明背景的其他版本之一(hdpi 等)。

    【讨论】:

      【解决方案5】:

      只需使用 8 位十六进制代码即可 示例:80DCDCDC 我长期使用它来提高透明度

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-09-24
        • 1970-01-01
        • 1970-01-01
        • 2011-09-15
        • 1970-01-01
        • 2011-02-24
        • 2016-12-08
        相关资源
        最近更新 更多