it-roy-ru.com

Использование Android-векторной графики при падении Lollipop

Я использую векторные рисования в 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>

Вы найдете ссылки на векторные элементы рисования вне app: srcCompat завершится с ошибкой до Lollipop. Тем не менее, AppCompat делает поддержка загрузки векторных рисованных объектов, когда на них есть ссылки в другом контейнер для рисования, такой как StateListDrawable, InsetDrawable, LayerDrawable, LevelListDrawable и RotateDrawable. Используя это indirection, вы можете использовать векторные рисунки в таких случаях, как TextView Android: атрибут drawableLeft, который обычно не может поддержка векторного рисования.

Когда я использую app:srcCompat все работает нормально, но когда я использую:

Android:background
Android:drawableLeft
Android:drawableRight
Android:drawableTop
Android:drawableBottom

на ImageView, ImageButton, TextView или EditText до Lollipop, он выдает исключение: 

Caused by: Android.content.res.Resources$NotFoundException: File res/drawable/search_toggle.xml from drawable resource ID #0x7f0200a9
62
Behzad Bahmanyar

Я думаю, что это происходит, потому что Вектор поддержки был отключен в последней версии библиотеки: 23.3.0

Согласно этому ПОСТ :

Для пользователей AppCompat мы решили удалить функциональность, которая позволяет использовать векторные рисунки из ресурсов на устройствах, предшествующих Lollipop, из-за проблем, обнаруженных в реализации в версии 23.2.0/23.2.1 (ISSUE 205236) . Использование app: srcCompat и setImageResource () продолжает работать.

Если вы посещаете проблему ВЫПУСК 205236 , кажется, что они включатся в будущем, но проблема с памятью не будет решена в ближайшее время:

В следующем выпуске я добавил opt-in API, где вы можете снова включить поддержку VectorDrawable, которая была удалена. Это идет с теми же предостережениями, что и раньше (использование памяти и проблемы с обновлением конфигурации).

У меня была похожая проблема. Таким образом, в моем случае я снова вернул все иконки, которые используют векторное рисование из ресурса, в изображения PNG (поскольку проблема с памятью будет происходить даже после того, как они предоставят возможность включить ее снова).

Я не уверен, что это лучший вариант, но, по моему мнению, он исправляет все сбои.

ОБНОВЛЕНИЕ

Они снова включили этот VectorDrawable в
Библиотека поддержки Android 23.4.0

Для пользователей AppCompat мы добавили API opt-in для повторного включения поддержки Vector Drawables из ресурсов (поведение в 23.2) через AppCompatDelegate.setCompatVectorFromResourcesEnabled (true) - имейте в виду, что это все еще может вызывать проблемы с использованием памяти и проблемы с обновлением экземпляров конфигурации, поэтому он по умолчанию отключен.

Может быть,, настройка build.gradle устарела, и вам просто нужно включить ее в соответствующих действиях (однако, нужно проверить).

Теперь, чтобы включить его, вы должны сделать:

public class MainActivity extends AppCompatActivity {
    static {
        AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
    }

    ...
}
64
W0rmH0le

У меня была та же проблема .. Но, выполнив много НИОКР, я получил ответ.

Для использования Imageview и ImageButton app: srcCompat = "@ drawable /...." И для других представлений, таких как Button, Textview, вместо использования drawableLeft/right ..." в XML, задайте drawables программно как :

button.setCompoundDrawablesWithIntrinsicBounds(AppCompatResources.getDrawable(mContext,R.drawable.ic_share_brown_18dp), null, null, null);

И используйте «AppCompatResources», чтобы получить отрисовку.

49
Shashank Kapsime

Чтобы уточнить другие очень хорошие ответы , вот схема которая может вам помочь. Он действителен, если у вас есть библиотека поддержки с 23.4.0 по крайней мере 25.1.0.

 VectorDrawable cheatsheet

47
David Ferrand

Ответ от Guillherme P довольно удивительный. Просто для того, чтобы сделать небольшое улучшение, вам не нужно добавлять эту строку в каждое действие, если вы добавили ее один раз в класс Application, она также будет работать. 

public class App extends Application {

static {
    AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
}

ПОМНИТЕ: Вам все еще нужно включить использование библиотеки поддержки в gradle: 

Android {
  defaultConfig {
    vectorDrawables.useSupportLibrary = true
  }
}

Кроме того, убедитесь, что вы используете версию библиотеки поддержки более позднюю, чем v23.4, когда Google вернул обратно поддержку Drawable Containers для VectorDrawables ( примечание к выпуску )

Обновление

И для изменения кода:

  1. Обязательно обновляйте до app:srcCompat каждое место, которое принимает атрибут Android:src (IDE предупредит вас, если оно недопустимо, как для тега <bitmap>).
  2. Для атрибутов 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);
    }
    
33
Benny

У меня такая же проблема. И исправить это, удалив 

vectorDrawables.useSupportLibrary = true

Моя целевая версия 25 и поддержка библиотеки

 compile 'com.Android.support:appcompat-v7:25.3.1'
11
Rajesh Nasit

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 или аналогичный.

8
cesards

Много НИОКР, наконец, получим это решение для сбоев на устройствах до Lollipop.

Для просмотра изображений

  • использовать приложение: srcCompat вместо Android: src

Для TextView/EditText

  • Удалите drawableleft , drawableright .... и установите из нарисованного Java-кода.

txtview.setCompoundDrawablesWithIntrinsicBounds (AppCompatResources.getDrawable (EventDetailSinglePage.this, R.drawable.ic_done_black_24_n), нуль, ноль, ноль);

Для Build.gradle

vectorDrawables.useSupportLibrary = true

5
Jatin Mandanka

Для тех, кто обновляет до Android Gradle 3.0 и выше, нет необходимости использовать AppCompatDelegate.setCompatVectorFromResourcesEnabled(true) или устанавливать vectorDrawables.useSupportLibrary = true (добавить это вызовет проблему) и использовать app:srcCompat, это просто работает.

У меня уйдет два дня, чтобы выяснить это, и я не нашел никаких связанных документов в документации Google ...

4
Geng Jiawen

Я использую 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));
2
Parag Kadam

Просто наложите вектор, отображаемый в список состояний, и проблема будет решена.

Например, у вас есть стрелка назад векторное изображение:

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. Если вы не перекрываете их, это не удастся.

0
mr.boyfox

Самый простой способ использования:

  app:drawableRightCompat ="@drawable/ic_mobilelogin"
  app:drawableEndCompat="@drawable/ic_mobilelogin"
app:srcCompat="@drawable/ic_mobile"

и ... просто используйте приложение: ** Compat для совместимости

Также добавьте поддержку build.gradle (Модуль)

Android {
 defaultConfig {
vectorDrawables.useSupportLibrary = true
               }
        }
0
Hamed Jaliliani