web-dev-qa-db-fra.com

Changer la couleur de remplissage de la ressource vectorielle dans Android Studio

Android Studio prend désormais en charge les ressources vectorielles sur 21 ans et plus et générera des fichiers pngs pour les versions inférieures au moment de la compilation. J'ai un élément vectoriel (à partir des icônes de matériau) pour lequel je souhaite modifier la couleur de remplissage. Cela fonctionne sur 21+, mais les pngs générés ne changent pas de couleur. Y a-t-il un moyen de faire cela?

<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"/>
140
Patrick

Ne modifiez pas les ressources vectorielles directement. Si vous utilisez un vecteur pouvant être dessiné dans un ImageButton, choisissez simplement votre couleur dans 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" />
280
YYYY-MM-DD

Tu peux le faire.

MAIS vous ne pouvez pas utiliser les références @color pour les couleurs (..lame), sinon cela ne fonctionnera que pour 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"/>
86
urSus

Comme indiqué dans d'autres réponses, n'éditez pas le vecteur dessiné directement, vous pouvez plutôt colorer le code Java, comme ceci:

    mWrappedDrawable = mDrawable.mutate();
    mWrappedDrawable = DrawableCompat.wrap(mWrappedDrawable);
    DrawableCompat.setTint(mWrappedDrawable, mColor);
    DrawableCompat.setTintMode(mWrappedDrawable, PorterDuff.Mode.SRC_IN);

Et dans un souci de simplicité, j'ai créé une classe d'assistance:

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;
    }
}

Pour l'utiliser, procédez comme suit:

    DrawableHelper
            .withContext(this)
            .withColor(R.color.white)
            .withDrawable(R.drawable.ic_search_24dp)
            .tint()
            .applyTo(mSearchItem);

Ou:

    final Drawable drawable = DrawableHelper
            .withContext(this)
            .withColor(R.color.white)
            .withDrawable(R.drawable.ic_search_24dp)
            .tint()
            .get();

    actionBar.setHomeAsUpIndicator(drawable);
62

Pour changer la couleur de l'image vectorielle, vous pouvez utiliser directement 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" />

Pour changer de couleur par programmation

ImageView ivVectorImage = (ImageView) findViewById(R.id.ivVectorImage);
ivVectorImage.setColorFilter(getResources().getColor(R.color.colorPrimary));
33
Rana Ranvijay Singh

Actuellement, la solution de travail est Android: fillColor = "# FFFFFF"

Rien ne fonctionnait pour moi sauf un codage dur dans le vecteur

<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"/>

Cependant, les couleurs de remplissage et les teintes pourraient fonctionner bientôt. S'il vous plaît voir cette discussion pour plus d'informations:

https://code.google.com/p/Android/issues/detail?id=186431

Les couleurs peuvent également être collées dans le cache afin de supprimer l’application pour tous les utilisateurs.

15
sivi

Android studio prend désormais en charge les vecteurs pré-Lollipop. Pas de conversion PNG. Vous pouvez toujours changer votre couleur de remplissage et cela fonctionnera.

Dans votre ImageView, utilisez

 app:srcCompat="@drawable/ic_more_vert_24dp"

Dans ton dossier,

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

 compile 'com.Android.support:design:23.4.0'
8
Sayooj Valsan

Mise à jour: AppCompat support

Autres réponses indiquant si Android:tint ne fonctionnera que sur plus de 21 périphériques uniquement, AppCompat ( à partir de v23.2.0 et supérieur ) = fournit maintenant un traitement rétrocompatible de l'attribut teinte.

La marche à suivre consisterait donc à utiliser AppCompatImageView et app:srcCompat (dans l'espace de noms AppCompat) au lieu de Android:src (espace de noms Android).

Voici un exemple:

<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" />

Et n'oubliez pas d'activer le support de dessin vectoriel dans Gradle:

vectorDrawables.useSupportLibrary = true 
4
pulp_fiction

Ajoutez cette bibliothèque au Gradle pour activer le vecteur de couleur pouvant être dessiné dans les anciens appareils Android.

compile 'com.Android.support:palette-v7:26.0.0-alpha1'

et re sync gradle. Je pense que ça va résoudre le problème.

2
Sid

si vous regardez pour supporter l'ancienne version pre lolipop

utiliser le même code XML avec quelques modifications

au lieu de la normale ImageView --> AppCompatImageView

au lieu de Android:src --> app:srcCompat

voici l'exemple

<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" />

ne pas oublier de mettre à jour votre diplôme comme @ Sayooj Valsan mention

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

 compile 'com.Android.support:design:23.4.0'

Notice Pour tout vecteur d’utilisation, ne donnez jamais votre référence de vecteur à une couleur comme celle-ci Android:fillColor="@color/primary" donne sa valeur hexadécimale.

2
Mina Fawzy

Si les vecteurs n'affichent pas de couleurs définies individuellement à l'aide de fillColor, ils sont peut-être définis sur un paramètre de widget par défaut.

Essayez d’ajouter app:itemIconTint="@color/Lime" à activity_main.xml pour définir un type de couleur par défaut pour les icônes de widget.

<?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>

VectorDrawable @ developers.Android

1
lubi