एंड्रॉइड स्टूडियो में वेक्टर संपत्ति पर रंग भरें


169

एंड्रॉइड स्टूडियो अब 21+ पर वेक्टर परिसंपत्तियों का समर्थन करता है और संकलन समय पर कम संस्करणों के लिए pngs उत्पन्न करेगा। मेरे पास एक सदिश संपत्ति है (मटेरियल आइकनों से) जिसे मैं भरना रंग बदलना चाहता हूं। यह 21+ पर काम करता है, लेकिन उत्पन्न pngs रंग नहीं बदलते हैं। क्या इसे करने का कोई तरीका है?

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

जवाबों:


333

वेक्टर परिसंपत्तियों को सीधे संपादित न करें। यदि आप एक ImageButton में एक सदिश drawable का उपयोग कर रहे हैं, तो बस अपना रंग चुनें 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" />

24
टिनिंग केवल 21+ उपकरणों पर काम करता है, क्या आपके पास प्री-लॉलीपॉप डिवाइसों के लिए कोई सुझाव है
मैडिट

12
android: API के बाद से सभी एंड्रॉइड वर्जन पर टिंट काम करता है। आप क्या मतलब है drawableTint है।
YYYY-MM-DD

31
android:tintके बाद होना चाहिएandroid:src
EmmanuelMess

5
किस बारे drawableLeftमें है Button?
प्रतीक बुटानी

8
@ मुदित fillColor = "# colorvalue" के साथ एक वेक्टर का उपयोग करने की कोशिश करते हैं, एक @ रंग संदर्भ का उपयोग न करें क्योंकि वे केवल एसडीके 21+ वैक्टर के लिए काम करते हैं (इसलिए उत्पन्न PNG के लिए नहीं)
PieterAelse

95

तुम कर सकते हो।

लेकिन आप रंगों (..) के लिए @ रंग संदर्भ का उपयोग नहीं कर सकते, अन्यथा यह केवल एल + के लिए काम करेगा

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


11
यह स्वीकृत उत्तर होना चाहिए! @color संदर्भ वैक्टर में काम नहीं करते पूर्व लॉलीपॉप (ताकि वेक्टर -> पीएनजी रूपांतरण) code.google.com/p/android/issues/detail?id=186431
PieterAelse

5
@color संदर्भ अब सभी एंड्रॉइड संस्करणों के लिए fillColor विशेषता के लिए उपयोग किया जा सकता है, हालांकि यह रंग राज्य सूचियों का समर्थन नहीं करता है।
आईआईटी

ऐसा लगता है कि सदिश राज्य सूचियों को करने का तरीका AnimatedStateListDrawable s
gMale

1
@ मुझे इसे सक्षम करने के लिए क्या करना होगा? मेरे लिए काम करने के लिए प्रतीत नहीं होता
ursus

@ पीटर मुझे यकीन नहीं है, क्या होगा यदि आप एक ही संपत्ति का उपयोग करना चाहते हैं, लेकिन विभिन्न पृष्ठभूमि (पिछले उत्तर में जैसे संकेत) के साथ। आपके समाधान में आपके पास एक ही संसाधन के कई उदाहरण होंगे, लेकिन अलग-अलग रंग भरें
एंटोन माकोव

71

जैसा कि अन्य उत्तरों में कहा गया है, वेक्टर ड्राएबल को सीधे संपादित न करें, इसके बजाय आप जावा कोड में टिंट कर सकते हैं, जैसे:

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

हाय Filipe, आपके उत्तर के लिए धन्यवाद। क्या आपके पास एक पुस्तकालय, स्निप्ड कोड जीथब है जहां हम लाइसेंस देख सकते हैं? धन्यवाद :)
विंसेंट डी।

2
नोप वाइसेंट, कोई लाइसेंस नहीं। इसका समाधान इतना सरल है कि मुझे लगता है कि यहां उपयोग किया जाने वाला बिल्डर पैटर्न आवश्यक नहीं है। लेकिन कोई भी बिना लाइसेंस के इस समाधान और उपयोग का लाभ ले सकता है।
फ़िलिप बेइज़रा डी सूसा

बहुत बढ़िया जवाब! ठीक वैसे ही काम करता है जैसे मुझे ज़रूरत है
इयोन

1
@VincentD। SO वेब पेज पाद लेख कहता है कि "उपयोगकर्ता द्वारा अपेक्षित योगदान के साथ cc by-sa 3.0 के तहत लाइसेंस प्राप्त किया गया"
शेल्फ़

इसने मेरे लिए कुछ बदलावों के साथ काम किया। आपके सहयोग के लिए धन्यवाद।
एंड्रे लुइज़ रीस

36

वेक्टर छवि रंग बदलने के लिए आप सीधे एंड्रॉइड का उपयोग कर सकते हैं : 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));

getColor () पदावनत है
डेविड

TextView के ड्रा करने योग्य *** के लिए इसका उपयोग कैसे करें?
हेमंत कौशिक

getColor (ResId) को हटा दिया गया है @ डेविड, लेकिन getColor(ResId, Theme)ऐसा नहीं है। या आप उपयोग कर सकते हैं ResourcesCompat.getColor(getResources(), R.color.primary, null);यदि आप विषय के बारे में परवाह नहीं करते हैं ... या यदि आपका संदर्भ / नीति प्रतिनिधि एक गतिविधि है, तो आप getTheme()उस अंतिम पैरामीटर के लिए कर सकते हैं ।
मार्टिन मार्कोसिनी

15

वर्तमान में वर्किंग सॉल्यूशन एंड्रॉइड है: 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"/>

हालाँकि, फिल्कोलर और टिंट जल्द ही काम कर सकते हैं। अधिक जानकारी के लिए कृपया इस चर्चा को देखें:

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

इसके अलावा रंग कैश में चिपक जाते हैं ताकि सभी उपयोगकर्ताओं के लिए ऐप हटाने में मदद मिल सके।


7

एंड्रॉइड स्टूडियो अब वैक्टर प्री-लॉलीपॉप का समर्थन करता है। कोई पीएनजी रूपांतरण नहीं। आप अभी भी अपने भरने का रंग बदल सकते हैं और यह काम करेगा।

आप ImageView में, का उपयोग करें

 app:srcCompat="@drawable/ic_more_vert_24dp"

आपकी फ़ाइल में,

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

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

10
सवाल यह है कि "सदिश भरण रंग कैसे बदलें", न कि "सदिश संपत्ति का उपयोग कैसे करें"
लियो डायरोडोडर

5

अद्यतन: AppCompatसमर्थन

यदि android:tintकेवल 21+ डिवाइसों पर ही काम करेगा, तो अन्य जवाब में , AppCompat ( v23.2.0 और इसके बाद के संस्करण ) अब टिंट विशेषता का एक बैकवर्ड संगत हैंडलिंग प्रदान करता है।

तो, कार्रवाई के पाठ्यक्रम का उपयोग किया जाएगा AppCompatImageViewऔर app:srcCompat(AppCompat नाम स्थान में) के बजाय android:src(एंड्रॉयड नाम स्थान)।

यहाँ एक उदाहरण है (AndroidX: यह androidx.appcompat.widget.AppCompatImage.net है ;)::

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

और ग्रेड में वेक्टर ड्रिबल समर्थन को सक्षम करने के लिए मत भूलना:

vectorDrawables.useSupportLibrary = true 

बस एक अद्यतन। आजकल AppCompatImageViewअंडर हैandroidx.appcompat.widget.AppCompatImageView
Roc Boronat

2

पुराने लाइब्रेरी डिवाइसेस में कलर वेक्टर ड्रॉबल इनेबल करने के लिए इस लाइब्रेरी को ग्रैडल में जोड़ें।

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

और फिर से सिंक सिंक करें। मुझे लगता है कि यह समस्या को हल करेगा।


2

यदि वैक्टर व्यक्तिगत रूप से सेट कलर का उपयोग नहीं कर रहे हैं, तो उन्हें एक डिफ़ॉल्ट विजेट पैरामीटर पर सेट किया जा सकता है।

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>

VectorDrawable @ Developers.android


एंड्रॉइड स्टूडियो में इस क्षेत्र में svg xml में 3.6 परिवर्तन: android: fillColor = "# FFFFC400"
a_subscriber

1

यदि आप पुराने संस्करण प्री लॉलीपॉप का समर्थन करना चाहते हैं

कुछ परिवर्तनों के साथ एक ही 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" />

@ Sayooj Valsan उल्लेख के रूप में अपने gradle को अपडेट करना न भूलें

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

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

सूचना किसी भी एक वेक्टर का उपयोग न करें, कभी भी अपने वेक्टर को कभी भी इस तरह से रंग न दें जैसे कि यह android:fillColor="@color/primary"अपने हेक्स मूल्य देता है।


क्यों कभी नहीं का उपयोग @colorकरने के लिए fillcolor?
होसिनिट

0

एक का उपयोग नहीं करने वालों के लिए ImageView, निम्नलिखित ने मेरे लिए एक सादा काम किया View(और इसलिए व्यवहार को किसी भी तरह के दृष्टिकोण पर दोहराया जाना चाहिए)

<View
    android:background="@drawable/ic_reset"
    android:backgroundTint="@color/colorLightText" />
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.