Я использую векторные чертежи в Android до Lollipop, и это некоторые из моих библиотек и версий инструментов:
- Android Studio: 2.0
- Плагин Android Gradle: 2.0.0
- Инструменты сборки: 23.0.2
- Библиотека поддержки Android: 23.3.0
Я добавил это свойство на уровне своего приложения Build.Gradle
android {
defaultConfig {
vectorDrawables.useSupportLibrary = true
}
}
Также стоит упомянуть, что я использую дополнительную возможность рисования, такую как LayerDrawable (layer_list), как указано в официальном блоге Android ( ссылка здесь ), для настройки чертежей для векторных чертежей внеapp:srcCompat
<level-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/search"/>
</level-list>
Вы найдете прямую ссылку на векторные чертежи вне приложения: srcCompat завершится ошибкой до Lollipop. Однако AppCompat поддерживает загрузку векторных чертежей, когда на них ссылаются в другом контейнере для рисования, таком как StateListDrawable, InsetDrawable, LayerDrawable, LevelListDrawable и RotateDrawable. Используя это косвенное обращение, вы можете использовать векторные чертежи в таких случаях, как атрибут TextView android: drawableLeft, который обычно не поддерживает векторные чертежи.
Когда я использую app:srcCompat
все работает нормально, но когда я использую:
android:background
android:drawableLeft
android:drawableRight
android:drawableTop
android:drawableBottom
на ImageView
, ImageButton
, TextView
или EditText
до леденца, он бросает expection:
Caused by: android.content.res.Resources$NotFoundException: File res/drawable/search_toggle.xml from drawable resource ID #0x7f0200a9
источник
Ответы:
ПОСЛЕДНЕЕ ОБНОВЛЕНИЕ - июнь / 2019
Библиотека поддержки немного изменилась с момента первоначального ответа. Теперь даже плагин Android для Gradle может автоматически генерировать PNG во время сборки. Итак, ниже представлены два новых подхода, которые должны работать в наши дни. Вы можете найти больше информации здесь:
Поколение PNG
Gradle может автоматически создавать изображения PNG из ваших ресурсов во время сборки. Однако при таком подходе поддерживаются не все элементы xml . Это решение удобно, потому что вам не нужно ничего менять в коде или в build.gradle. Просто убедитесь, что вы используете Android Plugin 1.5.0 или выше и Android Studio 2.2 или выше .
Я использую это решение в своем приложении и отлично работает. Дополнительный флаг build.gradle не требуется. Никаких взломов не требуется. Если вы перейдете в / build / generated / res / pngs / ..., вы увидите все сгенерированные PNG.
Итак, если у вас есть простой значок (поскольку поддерживаются не все элементы xml), это решение может сработать для вас. Просто обновите Android Studio и плагин Android для Gradle.
Библиотека поддержки
Возможно, это решение, которое подойдет вам. Если вы пришли сюда, это означает, что ваша Android Studio не генерирует PNG автоматически. Итак, ваше приложение дает сбой.
Или, может быть, вы вообще не хотите, чтобы Android Studio генерировала PNG.
В отличие от этого «автоматического создания PNG», которое поддерживает подмножество элементов XML, это решение поддерживает все теги xml. Итак, у вас есть полная поддержка вашего векторного рисования.
Вы должны сначала обновить свой build.gradle, чтобы поддерживать его:
android { defaultConfig { // This flag will also prevents Android Studio from generating PNGs automatically vectorDrawables.useSupportLibrary = true } } dependencies { // Use this for Support Library implementation 'com.android.support:appcompat-v7:23.2.0' // OR HIGHER // Use this for AndroidX implementation 'androidx.appcompat:appcompat:1.1.0' // OR HIGHER }
А затем используйте
app:srcCompat
вместоandroid:src
при загрузкеVectorDrawables
. Не забывай об этом.Для
TextView
, если вы используетеandroidx
версию библиотеки поддержки, вы можете использоватьapp:drawableLeftCompat
(или справа, сверху, снизу) вместоapp:drawableLeft
В случае
CheckBox
/RadioButton
используйтеapp:buttonCompat
вместоandroid:button
.Если вы не используете
androidx
версию библиотеки поддержки и вашminSdkVersion
она17
или выше, или вы используете кнопку, вы можете попытаться установить программно черезDrawable icon = AppCompatResources.getDrawable(context, <drawable_id>); textView.setCompoundDrawablesWithIntrinsicBounds(<leftIcon>,<topIcon>,<rightIcon>,<bottomIcon>);
ОБНОВЛЕНИЕ - июль / 2016
Они снова включили VectorDrawable в
библиотеке поддержки Android 23.4.0.
Может быть ,
build.gradle
настройка устарела, и вам просто нужно включить ее в надлежащих действиях (однако необходимо проверить).Теперь, чтобы включить его, вы должны сделать:
public class MainActivity extends AppCompatActivity { static { AppCompatDelegate.setCompatVectorFromResourcesEnabled(true); } ... }
Оригинальный ответ - апрель 2016 г.
Я думаю, это происходит потому, что Support Vector был отключен в последней версии библиотеки: 23.3.0
Согласно этому посту :
Если вы посетите вопрос ISSUE 205236 , кажется, что они будут включены в будущем, но проблема с памятью будет исправлена не скоро:
У меня была аналогичная проблема. Итак, в моем случае я снова вернул все значки, которые используют векторные изображения из ресурса, в изображения PNG (поскольку проблема с памятью будет возникать даже после того, как они предоставят возможность снова включить ее).
Не уверен, что это лучший вариант, но, на мой взгляд, он исправляет все сбои.
источник
vectorDrawables.useSupportLibrary = true
peroperty, чтобы снова включить создание файлов png во время сборки ?У меня такая же проблема. Но, проводя много исследований и разработок, я получил ответ.
Для использования Imageview и ImageButton,
app:srcCompat="@drawable/...."
а также для других представлений, таких как Button, Textview, вместо использования"drawableLeft/right..."
в XML, программно укажите чертежи как:button.setCompoundDrawablesWithIntrinsicBounds(AppCompatResources.getDrawable(mContext,R.drawable.ic_share_brown_18dp), null, null, null);
И используйте «AppCompatResources», чтобы получить возможность рисования.
источник
Чтобы уточнить другие очень хорошие ответы , вот диаграмма, которая может вам помочь. Это действительно, если у вас есть библиотека поддержки от 23.4.0 до 25.1.0.
источник
Ответ от Guillherme P довольно крутой . Чтобы внести небольшое улучшение, вам не нужно добавлять эту строку в каждое действие, если вы добавили ее один раз в класс Application, она также будет работать.
public class App extends Application { static { AppCompatDelegate.setCompatVectorFromResourcesEnabled(true); }
ПОМНИТЕ: вам все равно нужно включить использование библиотеки поддержки в gradle:
android { defaultConfig { vectorDrawables.useSupportLibrary = true } }
Кроме того, убедитесь, что вы используете версию библиотеки поддержки выше, чем v23.4, когда Google вернул поддержку Drawable Containers для VectorDrawables ( примечание к выпуску )
Обновить
И для изменения кода:
app:srcCompat
все места, которые принимаютandroid:src
атрибут (IDE предупредит вас, если он недействителен, как для<bitmap>
тега).Для
drawableLeft
,drawableStart
,drawableRight
,drawableEnd
атрибутов , используемых вTextView
и подобные взгляды, вы должны установить их программно на данный момент. Пример настройкиdrawableStart
:Drawable drawable = AppCompatResources.getDrawable( getContext(), R.drawable.your_vector_drawable); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { textView.setCompoundDrawablesRelativeWithIntrinsicBounds(drawable, null, null, null); }
источник
У меня такая же проблема. И исправить, удалив
vectorDrawables.useSupportLibrary = true
Моя целевая версия - 25, а библиотека поддержки -
compile 'com.android.support:appcompat-v7:25.3.1'
источник
vectorDrawables.useSupportLibrary = true
VectorDrawables на pre-lollipop должен нормально работать без использования
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
Если вы хотите использовать VectorDrawables внутри ImageViews, вы можете использовать атрибут,
srcCompat
и он будет работать, но внутри кнопок или TextViews этого не произойдет , поэтому вам нужно обернуть Drawable в InsetDrawable или LayerDrawable. Я обнаружил еще один трюк: если вы используете привязку данных, вы можете сделать это:android:drawableLeft="@{@drawable/vector_ic_access_time_24px}" android:drawableStart="@{@drawable/vector_ic_access_time_24px}"
Это сработает волшебным образом, я не исследовал, что происходит за кулисами, но я предполагаю, что TextView использует метод getDrawable из AppCompatResources или аналогичный.
источник
Много исследований и разработок, наконец, получение этого решения для сбоев на устройствах, предшествующих леденцу.
Для Imageview
Для TextView / EditText
Для Build.gradle
источник
Самый простой способ использования:
app:drawableRightCompat ="@drawable/ic_mobilelogin" app:drawableEndCompat="@drawable/ic_mobilelogin" app:srcCompat="@drawable/ic_mobile"
и ... просто используйте
app:**Compat
для совместимости. Также добавьте поддержкуbuild.gradle
(модуль)android { defaultConfig { vectorDrawables.useSupportLibrary = true } }
источник
Для тех, кто обновляется до Android Gradle 3.0 и выше, нет необходимости использовать
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true)
или устанавливатьvectorDrawables.useSupportLibrary = true
(добавление этого вызовет проблемы) и использоватьapp:srcCompat
, это просто работает.У меня два дня, чтобы разобраться в этом, и я не нашел никаких связанных документов в документации Google ...
источник
Я использую VectorDrawables на устройствах Pre-lollipop, и вот как я это делаю: -
Шаг 1. Поместите это в градиент уровня вашего приложения.
android { defaultConfig { vectorDrawables.useSupportLibrary = true } }
Шаг 2:
Поместите это в свой класс Application и не забудьте зарегистрировать свой класс Application в файле манифеста.
public class App extends Application { static { AppCompatDelegate.setCompatVectorFromResourcesEnabled(true); } }
Шаг 3:
Получите VectorDrawables, используя,
imageView.setImageDrawable(ContextCompat.getDrawable(this, R.drawable.my_vector_drawable));
источник
После использования приведенного ниже кода.
android { defaultConfig { vectorDrawables.useSupportLibrary = true } } public class App extends Application { static { AppCompatDelegate.setCompatVectorFromResourcesEnabled(true); }}
Тем не менее, проблема с векторными изображениями существует для следующих атрибутов:
DrawableEnd, DrawableStart, DrawableTop, DrawableBottom, Фон
В этом случае выполните следующие действия: вместо ссылки на векторное изображение напрямую используйте тег селектора в качестве промежуточного файла для рисования.
Пример:
ic_warranty_icon.xml
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="17dp" android:height="24dp" android:autoMirrored="true" android:viewportWidth="17" android:viewportHeight="24"> <path android:fillColor="#fff" android:pathData="M10.927,15.589l-1.549,0.355a7.47,7.47 0,0 1,-0.878 0.056c-4.136,0 -7.5,-3.364 -7.5,-7.5s3.364,-7.5 7.5,-7.5 7.5,3.364 7.5,7.5c0,3.286 -2.126,6.078 -5.073,7.089zM8.5,2a6.508,6.508 0,0 0,-6.5 6.5c0,3.583 2.917,6.5 6.5,6.5s6.5,-2.917 6.5,-6.5 -2.917,-6.5 -6.5,-6.5z" />
safe_ic_warranty_icon.xml
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@drawable/ic_warranty_icon" /> </selector>
Ваш TextView / Layout.
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:drawableStart="@drawable/ic_warranty_icon" /> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/ic_warranty_icon" />
источник
selector
Мы попробовали 3 вещи
vectorDrawables.useSupportLibrary = true
Установка setCompatVectorFromResourcesEnabled в классе Application
static { AppCompatDelegate.setCompatVectorFromResourcesEnabled(true); }
И использовать
app:srcCompat
Но даже после этого он не работал с
Resources$NotFoundException: File res/drawable/$my_icon__0.xml from color state list resource ID #0x7f080008
затем мы выяснили, что у нашего SVG есть тег Gradient. Преобразование тега градиента в отдельные пути для API <= 23 ниже и с использованием того же SVG API> = 24 работало.
Получил помощь от этого ответа https://stackoverflow.com/a/47783962/2171513
источник
Я боролся с этим часами.
Я перепробовал все, о чем мне говорили эти ответы, но мое приложение не переставало давать сбой. Я удалил эту строку:
app:srcCompat="@drawable/keyboard"
и мое приложение перестало давать сбой. а затем, когда я добавил то же самое, он снова начал вылетать. Я решил открыть этот файл и увидел ошибку в первой строке:Я щелкнул правой кнопкой мыши файл и выбрал «Показать в проводнике», и он был не в папке с возможностью рисования, а в каталоге drawable-v24. Поэтому я скопировал его и вставил в каталог с возможностью рисования и, наконец, избавился от сбоев.
источник
Просто наложите вектор, отображаемый в списке состояний, тогда проблема будет решена.
Например, у вас есть векторное изображение со стрелкой назад:
ic_back_arrow.xml
да, вы должны наложить его на список слоев xml (ic_back_arrow_vector_vector.xml):
<?xml version="1.0" encoding="utf-8"?> <layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@drawable/ic_back_arrow"/> </layer-list>
Потому что логика:
vectorDrawables.useSupportLibrary = true
а также
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
не поможет вам на некоторых китайских устройствах и старых устройствах Samsung. Если не перекрыть их, ничего не получится.
источник
Предложение Гильерме П. не помогло мне. Я пошел дальше и принял решение использовать png там, где мне нужно делать что-то вне app: srcCompat, то есть drawableLeft, drawableRight и т. Д. Это было довольно легко внести, и у него нет потенциальных проблем с памятью AppCompatDelegate.setCompatVectorFromResourcesEnabled ( правда); вводит.
источник
Альтернативой ответу Бенни является создание
Activity
суперкласса:public abstract class VectorDrawableActivity extends AppCompatActivity { static { AppCompatDelegate.setCompatVectorFromResourcesEnabled(true); } //... }
Теперь расширение
VectorDrawableActivity
вместоAppCompatActivity
.источник