VectorDrawable: Недопустимый градиент меток

Я использую Android Asset Studio для создания векторных рисунков из SVG файлов, экспортированных из Zeplin, и, за исключением нескольких раз, работает нормально. Но сегодня я получил это исключение, когда пытался использовать сгенерированный вектор для рисования.

android.view.InflateException: Binary XML file line #0: Error inflating class <unknown>

И в той же трассировке стека:

Caused by: org.xmlpull.v1.XmlPullParserException: Binary XML file line #0: invalid drawable tag gradient

Я не очень много знаю о векторных отрисовках и SVG в Android. Разве градиенты не поддерживаются в векторных отрисовках? Есть ли какое-то решение этой проблемы или мне нужно использовать PNG?

Я использую версию библиотеки поддержки:

com.android.support:support-v4:26.1.0

Я использую

Android Studio 3.0

Вот файл VectorDrawable, созданный Android Asset Studio:

<vector 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:aapt="http://schemas.android.com/aapt"
    android:width="360dp"
    android:height="110dp"
    android:viewportWidth="360.0"
    android:viewportHeight="110.0">
    <path
        android:pathData="M82,46H0v64h360V46h-81.88v-0.3h-26.21c-14.25,0 -38.69,-6.2 -46.95,-25.93C200.99,10.25 193.27,0.52 180,0.47c-13.27,-0.05 -20.04,9.24 -24.75,19.3 -8.22,17.55 -24.66,26.19 -49.34,25.93H82V46z"
        android:fillType="evenOdd">
        <aapt:attr name="android:fillColor">
            <gradient 
                android:startY="0.41999998688697815" 
                android:startX="0.0" 
                android:endY="110.0" 
                android:type="linear" 
                android:endX="360.0">
                <item android:offset="0.0" android:color="#FFCB09FF" />
                <item android:offset="1.0" android:color="#FF8A06FF" />
            </gradient>
        </aapt:attr></path>
</vector>

Ссылка на оригинальный файл SVG: https://drive.google.com/file/d/1Lj62xJv5IpYR5Lle7w1kMsFXh6y5PijK/view?usp=sharing

Содержимое SVG при открытии в Sublime:

<svg xmlns="http://www.w3.org/2000/svg" width="360" height="110" viewBox="0 0 360 110">
    <defs>
        <linearGradient id="a" x1="0%" y1="0%" y2="100%">
            <stop offset="0%" stop-color="#CB09FF"/>
            <stop offset="100%" stop-color="#8A06FF"/>
        </linearGradient>
    </defs>
    <path fill="url(#a)" fill-rule="evenodd" d="M82 46H0v64h360V46h-81.876v-.299h-26.208c-14.25 0-38.69-6.198-46.946-25.93C200.99 10.252 193.27.52 180 .474c-13.27-.047-20.04 9.238-24.75 19.295-8.217 17.55-24.662 26.194-49.336 25.931H82V46z"/>
</svg>

Ответ 1

Свойство android: fillColor поддерживается только в ОС 7. 0+,

android: fillColor Определяет цвет, используемый для заполнения пути. Может быть цвет или, для SDK 24+, список состояний цвета или цвет градиента (см. GradientColor и GradientColorItem). Если это свойство анимировано, любое значение, установленное анимацией, переопределит исходное значение. нет заполнение пути рисуется, если это свойство не указано.

для более старых версий в каталоге /drawable мы можем разместить векторный актив без градиентов, например:

<vector android:height="24dp" android:viewportHeight="651.95"
    android:viewportWidth="531.48" android:width="24dp"
    xmlns:aapt="http://schemas.android.com/aapt" xmlns:android="http://schemas.android.com/apk/res/android">
    <path android:pathData="M386.8,30.2c-48.5,0 -76.1,18 -121.1,18s-72.6,-18 -121.1,-18c-87.9,0 -144.7,83.3 -144.7,186 0,92.9 160,350.5 265.7,350.5 112.9,0 265.7,-257.6 265.7,-350.5C531.5,113.5 474.7,30.2 386.8,30.2Z">
        <!--<aapt:attr name="android:fillColor">
            <gradient android:endX="212457.73219299316"
                android:endY="440836.2612554932"
                android:startX="212457.73219299316"
                android:startY="92857.94223999024" android:type="linear">
                <item android:color="#FFFC3A11" android:offset="0.0"/>
                <item android:color="#FFDA0300" android:offset="1.0"/>
            </gradient>
        </aapt:attr>-->
    </path>
    ...
    ...

и внутри /drawable-24 каталога с градиентами:

<vector android:height="24dp" android:viewportHeight="651.95"
    android:viewportWidth="531.48" android:width="24dp"
    xmlns:aapt="http://schemas.android.com/aapt" xmlns:android="http://schemas.android.com/apk/res/android">
    <path android:pathData="M386.8,30.2c-48.5,0 -76.1,18 -121.1,18s-72.6,-18 -121.1,-18c-87.9,0 -144.7,83.3 -144.7,186 0,92.9 160,350.5 265.7,350.5 112.9,0 265.7,-257.6 265.7,-350.5C531.5,113.5 474.7,30.2 386.8,30.2Z">
        <aapt:attr name="android:fillColor">
            <gradient android:endX="212457.73219299316"
                android:endY="440836.2612554932"
                android:startX="212457.73219299316"
                android:startY="92857.94223999024" android:type="linear">
                <item android:color="#FFFC3A11" android:offset="0.0"/>
                <item android:color="#FFDA0300" android:offset="1.0"/>
            </gradient>
        </aapt:attr>
    </path>
    ...
    ...

Ответ 3

Это решение работает для нас в build.gradle

defaultConfig {
vectorDrawables.useSupportLibrary = true
}

и используйте app:srcCompat вместо android:src при установке вектора для рисования с градиентом на ImageView.

Ответ 4

Попробуйте добавить команду поддержки векторов в графе приложения, т.е.

defaultConfig {
    vectorDrawables.useSupportLibrary = true
}

enter image description here

Ответ 5

Тег Gradient в SVG поддерживается с ОС Версии 7 и выше. Попробуйте комментировать тег градиента для версий ниже ОС версии 7.

Ответ 6

Ошибка, вызванная атрибутом android: fillColor; это потому что:

android: fillColor Определяет цвет, используемый для заполнения пути. Может быть цветом или, для SDK 24+, списком состояний цвета или цветом градиента (см. GradientColor и GradientColorItem). Если это свойство анимировано, любое значение, установленное анимацией, переопределит исходное значение. Заполнение пути не отображается, если это свойство не указано.

Если вы хотите использовать градиент в версии старше 24, вы можете использовать обходной путь:

-Edit ваш вектор (например, называется drawable/ic_vector.xml):

<vector 
xmlns:android="http://schemas.android.com/apk/res/android" 
xmlns:aapt="http://schemas.android.com/aapt"
android:width="360dp"
android:height="110dp"
android:viewportWidth="360.0"
android:viewportHeight="110.0">
<path
    android:pathData="M82,46H0v64h360V46h-81.88v-0.3h-26.21c-14.25,0 -38.69,-6.2 -46.95,-25.93C200.99,10.25 193.27,0.52 180,0.47c-13.27,-0.05 -20.04,9.24 -24.75,19.3 -8.22,17.55 -24.66,26.19 -49.34,25.93H82V46z"
    android:fillType="evenOdd">
    <!--<aapt:attr name="android:fillColor">
        <gradient 
            android:startY="0.41999998688697815" 
            android:startX="0.0" 
            android:endY="110.0" 
            android:type="linear" 
            android:endX="360.0">
            <item android:offset="0.0" android:color="#FFCB09FF" />
            <item android:offset="1.0" android:color="#FF8A06FF" />
        </gradient>
    </aapt:attr></path>-->

-Create еще один нарисованный ресурс, в который вставляется градиент как элемент:

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
    <shape android:shape="rectangle">
        <gradient 
            android:type="linear"
            android:startColor="#FFCB09FF"
            android:endColor="#FF8A06FF"
            android:angle="270">
        </gradient>
    </shape>
</item>
<item android:drawable="@drawable/ic_vector"/>

Надеюсь, я помог тебе!