Как правильно использовать обратно совместимый Vector Drawable с последней библиотекой поддержки Android?

Vector drawable был добавлен в библиотеку поддержки не так давно, и с тех пор в API было много изменений: флаги Gradle, блоки инициализатора, селекторы, пользовательские атрибуты XML и т. д. Вопрос в том, как это правильно использовать сейчас ( поддержка lib v25) в этих случаях:

  • ImageView
  • TextView рисуемый
  • Значок меню
  • Значок уведомления

XML и программно.


person Maksim Ostrovidov    schedule 18.11.2016    source источник


Ответы (2)


Добавьте последнюю версию библиотеки поддержки в build.gradle зависимости вашего приложения:

compile 'com.android.support:appcompat-v7:26.0.2'

и добавьте следующую строку в тот же файл:

android {
    ...
    defaultConfig {
        ...
        vectorDrawables.useSupportLibrary = true
    }
    ...
}

Импортируйте векторное изображение через Vector Asset Studio.

Все готово!


ImageView

XML

Используйте атрибут app:srcCompat вместо android:src:

<ImageView
    ...
    app:srcCompat="@drawable/your_vector" 
    ... />

Программно

Непосредственно из идентификатора ресурса:

imageView.setImageResource(R.drawable.your_drawable);

Установить как Drawable объект (например, для тонирования):

Drawable vectorDrawable 
                = AppCompatResources.getDrawable(context, R.drawable.your_vector);
imageView.setImageDrawable(vectorDrawable);

И если вы хотите установить оттенок:

DrawableCompat.setTint
             (vectorDrawable, ContextCompat.getColor(context, R.color.your_color));

TextView рисуемый

XML

Простого решения нет: XML-атрибут android:drawableTop(Bottom etc) не может обрабатывать векторные изображения в pre-Lollipop. Одним из решений является добавление блока инициализатора в действие. и оберните вектор в другой рисуемый XML. Во-вторых, для определения пользовательского TextView.

Программно

Установка ресурса напрямую не работает, вы должны использовать объект Drawable. Получите его так же, как и для ImageView, и установите его соответствующим методом:

textView.setCompoundDrawablesWithIntrinsicBounds(vectorDrawable, null, null, null);

Значок меню

Ничего особенного:

<item
    ...
    android:icon="@drawable/your_vector"
    ... />

menuItem.setIcon(R.drawable.your_vector);

Уведомления:

Это невозможно, вы должны использовать PNG :(

person Maksim Ostrovidov    schedule 18.11.2016
comment
1+ в обоих случаях. - person Harshad Pansuriya; 18.11.2016
comment
AppCompatResources.getDrawable работает хорошо, спасибо. Может кто-нибудь сказать мне, почему ContextCompat.getDrawable не работает с точно таким же кодом и выдает ошибку при использовании вектора? - person casolorz; 25.08.2017

Вам нужно добавить vectorDrawables.useSupportLibrary = true в ваш файл build.gradle:

// Gradle Plugin 2.0+  
 android {  
   defaultConfig {  
     vectorDrawables.useSupportLibrary = true  
    }  
 } 

Вы заметите, что этот новый атрибут существует только в версии 2.0 плагина Gradle. Если вы используете Gradle 1.5, вместо этого вы будете использовать:

// Gradle Plugin 1.5  
 android {  
   defaultConfig {  
     generatedDensities = []  
  }  

  // This is handled for you by the 2.0+ Gradle Plugin  
  aaptOptions {  
    additionalParameters "--no-version-vectors"  
  }  
 }  

Вам нужно добавить srcCompat в ваш ImageView:

<ImageView  
  android:layout_width="wrap_content"  
  android:layout_height="wrap_content"  
  app:srcCompat="@drawable/ic_add" /> 
person Yurii Bulan    schedule 08.12.2016