Android Studio에서 벡터 자산의 채우기 색상 변경


169

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

답변:


333

벡터 자산을 직접 편집하지 마십시오. 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" />

24
틴팅은 21+ 기기에서만 작동합니다. 롤리팝 이전 기기에 대한 제안이
— 있으십니까

12
android : tint는 APIv1 이후의 모든 Android 버전에서 작동합니다. 당신이 의미하는 것은 drawableTint입니다.
— YYYY-MM-DD

31
android:tint다음에 와야합니다android:src
— EmmanuelMess

5
어떤 약 drawableLeft에 Button?
— Pratik Butani

8
@mudit은 fillColor = "# colorvalue"로 벡터를 사용하려고 시도합니다. @ 색상 참조는 벡터에 대해 SDK 21+ 만 작동하므로 생성 된 PNG에는 적합하지 않으므로 @ 색상 참조를 사용하지 마십시오.
— PieterAelse

95

넌 할 수있어.

그러나 색상 (..lame)에 @color 참조를 사용할 수는 없습니다.

<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
이것이 정답입니다! @ 컬러 참조는 롤리팝 이전의 벡터 (그래서 벡터-> PNG 변환)에서 작동하지 않습니다. code.google.com/p/android/issues/detail?id=186431
— PieterAelse

5
@color 참조는 이제 모든 Android 버전의 fillColor 속성에 사용할 수 있지만 색상 상태 목록은 지원하지 않습니다.
— TheIT

벡터 상태 목록을 수행하는 방법은 AnimatedStateListDrawable s
— gMale을 사용하는 것 같습니다. gMale

1
@TheIT 어떻게 활성화해야합니까? 나를 위해 작동하지 않는 것
— urSus

@PieterAelse 확실하지 않습니다. 동일한 자산을 사용하고 싶지만 다른 배경을 가진 경우 (이전 답변과 같은 색조). 솔루션에는 리소스가 동일하지만 채우기 색상이 다른 여러 인스턴스가 있습니다.
— Anton Makov

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, 답변 주셔서 감사합니다. 라이센스를 볼 수있는 라이브러리, 코드 스니핑 코드 github이 있습니까? 고마워 :)
— Vincent D.

2
아뇨 Vicent, 라이센스가 전혀 없습니다. 해결책 너무 간단해서 여기에 사용 된 빌더 패턴이 필요하지 않은 것 같습니다. 그러나 누구나이 솔루션의 이점을 누리고 라이센스없이 사용할 수 있습니다.
— Filipe Bezerra de Sousa 1

좋은 답변입니다! 내가 원하는대로 작동
— Eoin

1
@VincentD. SO 웹 페이지 바닥 글에 "
— 귀하의

그것은 약간의 변화로 나를 위해 일했습니다. 도와 주셔서 감사합니다.
— André Luiz Reis

36

벡터 이미지 색상을 변경하려면 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));

getColor () 지원 중단됨
— David

TextView의 drawable에 사용하는 방법 ***?
— Hemant Kaushik

getColor (ResId)는 @David가 더 이상 사용되지 않지만 getColor(ResId, Theme)그렇지 않습니다. 또는 ResourcesCompat.getColor(getResources(), R.color.primary, null);테마에 관심이없는 경우 또는 컨텍스트 / 정책 대리인이 활동 인 경우 getTheme()마지막 매개 변수에 대해 수행 할 수 있습니다 .
— Martin Marconcini

15

현재 작업중인 soloution은 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 및 tint가 곧 작동 할 수 있습니다. 자세한 내용은이 토론을 참조하십시오.

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

또한 색상 mighr이 캐시에 붙어 있으므로 모든 사용자의 앱을 삭제하면 도움이 될 수 있습니다.


7

Android 스튜디오는 이제 롤리팝 사전 벡터를 지원합니다. 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'

10
문제는 "벡터 자산을 사용하는 방법"이 아니라 "벡터 채우기 색상을 변경하는 방법"입니다.
— Leo Droidcoder

5

업데이트 : AppCompat지원

android:tint21 개 이상의 장치에서만 작동 하는지 의심되는 다른 답변 에서는 AppCompat ( v23.2.0 이상 ) 에서 색조 속성의 하위 호환성을 제공합니다.

따라서 조치 과정 은 (Android 네임 스페이스) 대신 AppCompatImageView및 app:srcCompat(AppCompat 네임 스페이스에서)를 사용하는 것입니다 android:src.

다음은 예입니다 (AndroidX : 이것은 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에서 벡터 드로어 블 지원을 활성화하는 것을 잊지 마십시오.

vectorDrawables.useSupportLibrary = true 

그냥 업데이트. 요즘 AppCompatImageView은 아래에 있습니다androidx.appcompat.widget.AppCompatImageView
— Roc Boronat

2

이 라이브러리를 Gradle에 추가하여 오래된 Android 장치에서 색 벡터 드로어 블을 활성화하십시오.

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

gradle을 다시 동기화하십시오. 나는 그것이 문제를 해결할 것이라고 생각한다.


2

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>

VectorDrawable @ 개발자. 안드로이드


Android 스튜디오 3.6에서 svg xml 변경 : 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?
— HoseinIT

0

를 사용하지 않는 사람들을 ImageView위해 다음이 평범하게 작동했습니다 View(따라서 행동은 모든 종류의 관점에서 복제되어야 함)

<View
    android:background="@drawable/ic_reset"
    android:backgroundTint="@color/colorLightText" />
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.