Android Studio'da vektör öğesindeki dolgu rengini değiştirme


169

Android Studio artık 21+ üzerindeki vektör varlıklarını destekliyor ve derleme zamanında daha düşük sürümler için png üretecek. Dolgu rengini değiştirmek istediğim bir vektör varlığı (Malzeme Simgeleri) var. Bu 21+ üzerinde çalışır, ancak oluşturulan png'ler renk değiştirmez. Bunu yapmanın bir yolu var mı?

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

Yanıtlar:


333

Vektör varlıklarını doğrudan düzenlemeyin. ImageButton'da çizilebilir bir vektör kullanıyorsanız, renginizi seçin 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
renklendirme sadece 21+ cihazda çalışır, lolipop öncesi cihazlar için herhangi bir öneriniz var mı
mudit

12
android: tint APIv1'den bu yana tüm android sürümlerinde çalışır. Demek istediğin drawableTint.
YYYY-AA-GG

31
android:tintsonra olmalıandroid:src
EmmanuelMess

5
Ne hakkında drawableLeftyılında Button?
Pratik Butani

8
@mudit fillColor = "# colorvalue" ile bir vektör kullanmayı deneyin, @ color referansını kullanmayın, çünkü vektörler için yalnızca SDK 21+ çalışırlar (bu yüzden oluşturulan
PNG'ler

95

Bunu yapabilirsin.

AMA renkler (..lame) için @color referanslarını kullanamazsınız, aksi takdirde sadece L + için çalışır

<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
Bu kabul edilen cevap olmalı! @color referansları Lollipop öncesi vektörlerde çalışmaz (bu yüzden vektör -> PNG dönüşümü) code.google.com/p/android/issues/detail?id=186431
PieterAelse

5
@color referansları artık tüm Android sürümlerinde fillColor özniteliği için kullanılabilir, ancak renk durumu listelerini desteklemez.
TheIT

Vektör durum listeleri yapmanın yolu AnimatedStateListDrawable s
gMale ile

1
@TheIT etkinleştirmek için neyim var? Benim için çalışmıyor gibi görünüyor
urSus

@PieterAelse Emin değilim, aynı varlığı kullanmak istiyorsanız, ancak farklı geçmişlere sahipseniz (önceki yanıtta olduğu gibi renk tonları). Çözümünüzde, aynı kaynağa sahip ancak farklı dolgu rengine sahip birkaç örneğiniz olacak
Anton Makov

71

Diğer cevaplarda belirtildiği gibi, doğrudan çizilebilir vektörü düzenlemeyin, bunun yerine java kodunda renklendirebilirsiniz, şöyle:

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

Ve basitlik uğruna, yardımcı bir sınıf yarattım:

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

Kullanmak için aşağıdakileri yapın:

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

Veya:

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

    actionBar.setHomeAsUpIndicator(drawable);

Merhaba Filipe, Cevabınız için teşekkürler. Lisansı görebileceğimiz bir kütüphane, kesik kod github var mı? teşekkürler :)
Vincent D.

2
Hayır, Vicent, lisans yok. Çözüm o kadar basit ki, burada kullanılan Builder modelinin gerekli olmadığını tahmin ediyorum. Ancak herkes bu çözümden yararlanabilir ve lisanssız kullanabilir.
Filipe Bezerra de Sousa

Mükemmel cevap! Tam ihtiyacım gibi çalışıyor
Eoin

1
@VincentD. SO web sayfası altbilgisi "ilişkilendirme gerekli cc by-sa 3.0 altında lisanslanan kullanıcı katkıları" diyor
shelll

Bazı değişikliklerle benim için çalıştı. Yardımın için teşekkürler.
André Luiz Reis

36

Vektör görüntü rengini değiştirmek için doğrudan android kullanabilirsiniz : 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" />

Renkleri programlı olarak değiştirmek için

ImageView ivVectorImage = (ImageView) findViewById(R.id.ivVectorImage);
ivVectorImage.setColorFilter(getResources().getColor(R.color.colorPrimary));

getColor () kullanımdan kaldırıldı
David

TextView çekilebilir *** için nasıl kullanılır?
Hemant Kaushik

getColor (ResId) @David'da kullanımdan kaldırıldı, ancak getColor(ResId, Theme)değil. Veya ResourcesCompat.getColor(getResources(), R.color.primary, null);temayı önemsemiyorsanız kullanabilirsiniz ... veya bağlam / politika temsilciniz bir etkinlikse, getTheme()bu son parametre için yapabilirsiniz .
Martin Marconcini

15

Şu anda çalışan soloution android: fillColor = "# FFFFFF"

Vektörde sabit kodlama dışında hiçbir şey benim için çalışmadı

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

Ancak, dolgu rengi ve renk tonu yakında işe yarayabilir. Daha fazla bilgi için lütfen bu tartışmaya bakın:

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

Ayrıca renkler önbellekte yapışabilir böylece tüm kullanıcılar için app silmek yardımcı olabilir.


7

Android stüdyosu artık vektörleri lolipop öncesi destekliyor. PNG dönüşümü yok. Dolgu renginizi değiştirmeye devam edebilirsiniz ve çalışır.

ImageView'de şunu kullanın:

 app:srcCompat="@drawable/ic_more_vert_24dp"

Gradle dosyanızda,

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

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

10
Soru, "vektör varlığının nasıl değiştirileceği" değil, "vektör varlığının nasıl kullanılacağı" değil
Leo Droidcoder

5

Güncelleme: AppCompatdestek

android:tintYalnızca 21+ cihazda çalışıp çalışmayacağından şüphelenen diğer yanıtlar , AppCompat ( v23.2.0 ve üstü ) artık renk tonu özelliğinin geriye dönük olarak uyumlu bir şekilde işlenmesini sağlıyor.

Bu nedenle, eylemin yolu (Android ad alanı) yerine AppCompatImageViewve app:srcCompat(AppCompat ad alanında) kullanmak olacaktır android:src.

İşte bir örnek (AndroidX: Bu androidx.appcompat.widget.AppCompatImageView ;)):

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

Gradle'da vektör çekilebilir desteği etkinleştirmeyi unutmayın:

vectorDrawables.useSupportLibrary = true 

Sadece bir güncelleme. Bugünlerde AppCompatImageViewaltındaandroidx.appcompat.widget.AppCompatImageView
Roc Boronat

2

Eski android cihazlarda çizilebilir renk vektörünü etkinleştirmek için Gradle'a bu kütüphaneyi ekleyin.

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

ve yeniden senkronize eder. Sorunu çözeceğini düşünüyorum.


2

Vektörler fillColor kullanarak ayrı ayrı ayarlanmış renkleri göstermiyorsa, varsayılan bir widget parametresine ayarlanmış olabilirler.

app:itemIconTint="@color/lime"Widget simgeleri için varsayılan bir renk türü ayarlamak üzere activity_main.xml dosyasına eklemeyi deneyin .

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


Android studio 3.6 svg xml bu alanda değişiklik: android: fillColor = "# FFFFC400"
a_subscriber

1

eski sürüm lolipopunu desteklemek istiyorsanız

bazı değişikliklerle aynı xml kodunu kullan

normal yerine ImageView --> AppCompatImageView

onun yerine android:src --> app:srcCompat

işte örnek

<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 bahsettiği gibi gradle güncellemeyi unutma

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

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

Uyarı Herhangi bir kullanım için vektör asla bu gibi renk android:fillColor="@color/primary"için onaltılık değerini vermek gibi vektör referans vermeyin .


neden hiç kullanmak @coloriçin fillcolor?
HoseinIT

0

Bir kullanmayanlar için ImageView, aşağıdakiler benim için bir ovada çalıştı View(ve dolayısıyla davranış her türlü görünümde çoğalmalıdır)

<View
    android:background="@drawable/ic_reset"
    android:backgroundTint="@color/colorLightText" />
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.