Прозрачный адаптивный фон значка

Итак, я работаю над этим приложением в течение пары недель, и я начал создавать иконку. У меня Android Studio 3.0.1, и они, похоже, изменили способ создания образа, теперь у них есть адаптивные значки. Я сделал значок с прозрачным фоном для своего приложения. Раньше я просто менял бы форму на "none", и фон не генерировался. Но теперь это не вариант, если я не пойду на "наследие", которое бесполезно. Цвет фона, похоже, не поддерживает прозрачность. Даже если в 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>

Ответ 1

TL; DR Адаптивные значки не могут иметь прозрачный фон

Прозрачный фон будет непрозрачным черным.

Согласно исходному коду платформы Android 8.0, слой <background> по своей природе непрозрачен; как уже упоминалось в вопросе, рамки заполняют фон непрозрачным черным.

Фреймворк имеет класс AdaptiveIconDrawable, который рисует иконки адаптивного запуска. https://developer.android.com/reference/android/graphics/drawable/AdaptiveIconDrawable.html
Элемент <adaptive-icon> создает его экземпляр:

Этот класс также может быть создан с помощью XML-инфляции с использованием тега <adaptive-icon> в дополнение к динамическому созданию.

Исходный код метода draw в AdaptiveIconDrawable.java:

@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.

Таким образом, фон всегда будет непрозрачным, даже если вы установите прозрачный цвет фона, как на скриншоте ниже (из моего ответа на аналогичный вопрос).

NoAdaptive and Adaptive

Ответ 2

Вы сказали, что старый значок "бесполезен", но единственное логическое решение - использовать старый значок. Если вы вообще не создаете адаптивный значок, Android 8.0 и выше должны будут использовать устаревший значок. Кроме того, адаптивная иконка с прозрачным фоном является противоречивой концепцией, потому что главная особенность адаптивной пиктограммы состоит в том, что передний план содержится в форме, определенной OEM. Но если фон прозрачен, как может быть какая-либо форма? С тем же успехом вы можете спросить, как поставить квадрат.

Ответ 3

просто играть с 8-значным шестнадцатеричным кодом пример: 80DCDCDC я использую это долгое время для прозрачности