Change fill color on vector asset in Android Studio

后端 未结 12 1972
盖世英雄少女心
盖世英雄少女心 2020-12-02 04:09

Android Studio now supports vector assets on 21+ and will generate pngs for lower versions at compile time. I have a vector asset (from the Material Icons) that I want to c

12条回答
  •  没有蜡笔的小新
    2020-12-02 05:10

    As said in other answers, don't edit the vector drawable directly, instead you can tint in java code, like that:

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

    And for the sake of simplicity, I have created a helper class:

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

    To use just do the following:

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

    Or:

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

提交回复
热议问题