Изменение цвета заливки на векторном ресурсе в Android Studio
Android Studio теперь поддерживает векторные активы на 21+ и будет генерировать PNG для более низких версий во время компиляции. У меня есть векторный актив (из значков материалов), который я хочу изменить цвет заливки. Это работает на 21+, но сгенерированные png не меняют цвет. Есть ли способ сделать это?
<vector android:height="48dp" android:viewportHeight="24.0"
android:viewportWidth="24.0" android:width="48dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@color/primary" android:pathData="M9,16.17L4.83,12l-1.42,1.41L9,19 21,7l-1.41,-1.41z"/>
10 ответов:
не редактируйте векторные активы напрямую. Если вы используете вектор, который можно нарисовать в ImageButton, просто выберите свой цвет в
android:tint.<ImageButton android:layout_width="48dp" android:layout_height="48dp" android:id="@+id/button" android:src="@drawable/ic_more_vert_24dp" android:tint="@color/primary" />
вы можете сделать это.
но вы не можете использовать ссылки @color для цветов (..lame), в противном случае он будет работать только для L+
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="24dp" android:height="24dp" android:viewportWidth="24.0" android:viewportHeight="24.0"> <path android:fillColor="#FFAABB" android:pathData="M15.5,14h-0.79l-0.28,-0.27C15.41,12.59 16,11.11 16,9.5 16,5.91 13.09,3 9.5,3S3,5.91 3,9.5 5.91,16 9.5,16c1.61,0 3.09,-0.59 4.23,-1.57l0.27,0.28v0.79l5,4.99L20.49,19l-4.99,-5zm-6,0C7.01,14 5,11.99 5,9.5S7.01,5 9.5,5 14,7.01 14,9.5 11.99,14 9.5,14z"/>
как сказано в других ответах, не редактируйте вектор, который можно нарисовать напрямую, вместо этого вы можете подкрасить код java, например:
mWrappedDrawable = mDrawable.mutate(); mWrappedDrawable = DrawableCompat.wrap(mWrappedDrawable); DrawableCompat.setTint(mWrappedDrawable, mColor); DrawableCompat.setTintMode(mWrappedDrawable, PorterDuff.Mode.SRC_IN);и для простоты, я создал вспомогательный класс:
import android.content.Context; import android.graphics.PorterDuff; import android.graphics.drawable.Drawable; import android.os.Build; import android.support.annotation.ColorRes; import android.support.annotation.DrawableRes; import android.support.annotation.NonNull; import android.support.v4.content.ContextCompat; import android.support.v4.graphics.drawable.DrawableCompat; import android.view.MenuItem; import android.view.View; import android.widget.ImageView; /** * {@link Drawable} helper class. * * @author Filipe Bezerra * @version 18/01/2016 * @since 18/01/2016 */ public class DrawableHelper { @NonNull Context mContext; @ColorRes private int mColor; private Drawable mDrawable; private Drawable mWrappedDrawable; public DrawableHelper(@NonNull Context context) { mContext = context; } public static DrawableHelper withContext(@NonNull Context context) { return new DrawableHelper(context); } public DrawableHelper withDrawable(@DrawableRes int drawableRes) { mDrawable = ContextCompat.getDrawable(mContext, drawableRes); return this; } public DrawableHelper withDrawable(@NonNull Drawable drawable) { mDrawable = drawable; return this; } public DrawableHelper withColor(@ColorRes int colorRes) { mColor = ContextCompat.getColor(mContext, colorRes); return this; } public DrawableHelper tint() { if (mDrawable == null) { throw new NullPointerException("É preciso informar o recurso drawable pelo método withDrawable()"); } if (mColor == 0) { throw new IllegalStateException("É necessário informar a cor a ser definida pelo método withColor()"); } mWrappedDrawable = mDrawable.mutate(); mWrappedDrawable = DrawableCompat.wrap(mWrappedDrawable); DrawableCompat.setTint(mWrappedDrawable, mColor); DrawableCompat.setTintMode(mWrappedDrawable, PorterDuff.Mode.SRC_IN); return this; } @SuppressWarnings("deprecation") public void applyToBackground(@NonNull View view) { if (mWrappedDrawable == null) { throw new NullPointerException("É preciso chamar o método tint()"); } if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { view.setBackground(mWrappedDrawable); } else { view.setBackgroundDrawable(mWrappedDrawable); } } public void applyTo(@NonNull ImageView imageView) { if (mWrappedDrawable == null) { throw new NullPointerException("É preciso chamar o método tint()"); } imageView.setImageDrawable(mWrappedDrawable); } public void applyTo(@NonNull MenuItem menuItem) { if (mWrappedDrawable == null) { throw new NullPointerException("É preciso chamar o método tint()"); } menuItem.setIcon(mWrappedDrawable); } public Drawable get() { if (mWrappedDrawable == null) { throw new NullPointerException("É preciso chamar o método tint()"); } return mWrappedDrawable; } }для использования просто выполните следующие действия:
DrawableHelper .withContext(this) .withColor(R.color.white) .withDrawable(R.drawable.ic_search_24dp) .tint() .applyTo(mSearchItem);или:
final Drawable drawable = DrawableHelper .withContext(this) .withColor(R.color.white) .withDrawable(R.drawable.ic_search_24dp) .tint() .get(); actionBar.setHomeAsUpIndicator(drawable);
для изменения цвета векторного изображения вы можете напрямую использовать android:tint= "@color / colorAccent"
<ImageView android:id="@+id/ivVectorImage" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/ic_account_circle_black_24dp" android:tint="@color/colorAccent" />изменить цвет программно
ImageView ivVectorImage = (ImageView) findViewById(R.id.ivVectorImage); ivVectorImage.setColorFilter(getResources().getColor(R.color.colorPrimary));
В настоящее время работает решение android: fillColor= "#FFFFFF"
ничего не работало для меня, кроме жесткого кодирования в векторе
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="24dp" android:height="24dp" android:viewportWidth="24.0" android:fillColor="#FFFFFF" android:viewportHeight="24.0"> <path android:fillColor="#FFFFFF" android:pathData="M15.5,14h-0.79l-0.28,-0.27C15.41,12.59 16,11.11 16,9.5 16,5.91 13.09,3 9.5,3S3,5.91 3,9.5 5.91,16 9.5,16c1.61,0 3.09,-0.59 4.23,-1.57l0.27,0.28v0.79l5,4.99L20.49,19l-4.99,-5zm-6,0C7.01,14 5,11.99 5,9.5S7.01,5 9.5,5 14,7.01 14,9.5 11.99,14 9.5,14z"/>тем не менее, fillcolor и оттенок может работать в ближайшее время. Пожалуйста, смотрите это обсуждение для получения дополнительной информации:
https://code.google.com/p/android/issues/detail?id=186431
также цвета mighr stick в кэше, поэтому удаление приложения для всех пользователей может помочь.
Android studio теперь поддерживает векторы pre-lollipop. Преобразование в PNG. Вы все еще можете изменить цвет заливки и он будет работать.
в Вас ImageView, используйте
app:srcCompat="@drawable/ic_more_vert_24dp"в вашем файле gradle,
// Gradle Plugin 2.0+ android { defaultConfig { vectorDrawables.useSupportLibrary = true } } compile 'com.android.support:design:23.4.0'
обновление:
AppCompatподдержкадругие ответы подозревая, если
android:tintбудет работать только на 21+ устройств, AppCompat (v23. 2. 0 и выше) в настоящее время обеспечивает обратную совместимость обработку атрибута оттенок.Итак, курс действий будет использовать
AppCompatImageViewиapp:srcCompat(в пространстве имен AppCompat) вместоandroid:src(пространство имен Android).вот пример:
<android.support.v7.widget.AppCompatImageView android:id="@+id/credits_material_icon" android:layout_width="20dp" android:layout_height="20dp" android:layout_marginBottom="8dp" android:layout_marginLeft="16dp" android:layout_marginStart="16dp" android:scaleType="fitCenter" android:tint="#ffd2ee" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:srcCompat="@drawable/ic_dollar_coin_stack" />и не забудьте включить вектор drawable поддержка в gradle:
vectorDrawables.useSupportLibrary = true
если вы хотите поддержать старую версию pre lolipop
используйте тот же xml-код с некоторыми изменениями
вместо нормального
ImageView --> AppCompatImageViewвместо
android:src --> app:srcCompatвот пример
<android.support.v7.widget.AppCompatImageView android:layout_width="48dp" android:layout_height="48dp" android:id="@+id/button" app:srcCompat="@drawable/ic_more_vert_24dp" android:tint="@color/primary" />не забудьте обновить ваш gradle как @ Sayooj Valsan отметить
// Gradle Plugin 2.0+ android { defaultConfig { vectorDrawables.useSupportLibrary = true } } compile 'com.android.support:design:23.4.0'обратите внимание для любого использования вектора никогда никогда не давайте векторную ссылку на цвет, как этот
android:fillColor="@color/primary"дать его шестнадцатеричное значение .
добавить эту библиотеку в Gradle, чтобы включить цветной вектор drawable в старых устройствах android.
compile 'com.android.support:palette-v7:26.0.0-alpha1'и повторно синхронизировать gradle. Я думаю, что это решит проблему.
если векторы не показывают индивидуально установленные цвета с помощью fillColor, то они могут быть установлены в параметр виджета по умолчанию.
попробуйте добавить
app:itemIconTint="@color/lime"в activity_main.xml для установки типа цвета по умолчанию для значков виджета.<?xml version="1.0" encoding="utf-8"?> <android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/drawer_layout" android:layout_width="match_parent" android:layout_height="match_parent" android:fitsSystemWindows="true" tools:openDrawer="start"> <include layout="@layout/app_bar_main" android:layout_width="match_parent" android:layout_height="match_parent" /> <android.support.design.widget.NavigationView android:id="@+id/nav_view" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_gravity="start" android:fitsSystemWindows="true" app:headerLayout="@layout/nav_header_main" app:itemIconTint="@color/lime" app:menu="@menu/activity_main_drawer" /> </android.support.v4.widget.DrawerLayout>
Comments