【问题标题】:Change fill color on vector asset in Android Studio在 Android Studio 中更改矢量资产的填充颜色
【发布时间】:2015-12-31 17:10:36
【问题描述】:

Android Studio 现在支持 21+ 的矢量资源,并将在编译时为较低版本生成 png。我有一个要更改填充颜色的矢量资产(来自 Material Icons)。这适用于 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"/>

【问题讨论】:

    标签: android android-studio vector-graphics android-vectordrawable


    【解决方案1】:

    使用

    android:drawableTint="@color/primary"
    

    在activity_main.xml中

    【讨论】:

      【解决方案2】:

      对于我的 ImageButton,我使用 app:tint="@color/green" 而不是 android:tint

      【讨论】:

        【解决方案3】:

        如果矢量资源在 CardView 中,请尝试 card_view:tint="@color/secondary" 在 ImageView 中。 注意:将@color/secondary 替换为您想要的颜色。

        【讨论】:

          【解决方案4】:

          如果你想改变一个项目矢量图标的颜色,你可以使用这个:

          android:iconTint="@color/color"
          

          【讨论】:

          • 仅 API 26 及更高版本
          【解决方案5】:

          转到你的 MainActivity.java 并在此代码下方
          -> NavigationView navigationView = findViewById(R.id.nav_view);
          添加单行代码 -> navigationView.setItemIconTintList(null);
          即我的代码的最后一行

          我希望这可以解决您的问题。

          public class MainActivity extends AppCompatActivity {
          
              private AppBarConfiguration mAppBarConfiguration;
              @Override
              protected void onCreate(Bundle savedInstanceState) {
                  super.onCreate(savedInstanceState);
                  setContentView(R.layout.activity_main);
          
                  Toolbar toolbar = findViewById(R.id.toolbar);
                  setSupportActionBar(toolbar);
          
                  DrawerLayout drawer = findViewById(R.id.drawer_layout);
                  NavigationView navigationView = findViewById(R.id.nav_view);
                  navigationView.setItemIconTintList(null);
          

          【讨论】:

            【解决方案6】:

            更新:AppCompat 支持

            其他答案怀疑android:tint 是否仅适用于 21 台以上的设备,AppCompat(v23.2.0 及更高版本) 现在提供了向后兼容的 tint 属性处理.

            因此,行动方案是使用AppCompatImageViewapp:srcCompat(在AppCompat 命名空间中)而不是android:src(Android 命名空间)。

            这是一个例子(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 
            

            【讨论】:

            • 只是一个更新。现在AppCompatImageViewandroidx.appcompat.widget.AppCompatImageView
            【解决方案7】:

            对于那些不使用 ImageView 的人,以下内容在普通的 View 上对我有用(因此该行为应该在任何类型的视图上复制)

            <View
                android:background="@drawable/ic_reset"
                android:backgroundTint="@color/colorLightText" />
            

            【讨论】:

              【解决方案8】:

              不要直接编辑矢量资源。如果您在 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" />
              

              【讨论】:

              • 着色仅适用于 21+ 设备,您对棒棒糖前的设备有什么建议
              • android:tint 适用于自 APIv1 以来的所有 android 版本。你的意思是drawableTint。
              • android:tint 必须在android:src 之后
              • drawableLeft in Button 怎么样?
              • @mudit 尝试使用带有 fillColor="#colorvalue" 的矢量,不要使用 @ 颜色参考,因为它们仅适用于矢量的 SDK 21+(因此不适用于生成的 PNG)
              【解决方案9】:

              如果矢量没有显示使用 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 @ developers.android

              【讨论】:

              • 在 Android Studio 3.6 中更改 svg xml 这个字段:android:fillColor="#FFFFC400"
              【解决方案10】:

              将此库添加到 Gradle 以在旧的 android 设备中启用颜色矢量绘制。

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

              然后重新同步 gradle。我认为它会解决问题。

              【讨论】:

                【解决方案11】:

                如果您希望支持旧版本的 pre lolipop

                使用相同的 xml 代码并进行一些更改

                而不是正常的ImageView --&gt; AppCompatImageView

                而不是android:src --&gt; 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" />
                

                不要忘记更新你的 gradle 作为@Sayooj Valsan 提到

                // Gradle Plugin 2.0+  
                 android {  
                   defaultConfig {  
                     vectorDrawables.useSupportLibrary = true  
                   }  
                 }  
                
                 compile 'com.android.support:design:23.4.0'
                

                注意对于任何使用矢量的人,永远不要给矢量引用这样的颜色 android:fillColor="@color/primary" 给出它的十六进制值。

                【讨论】:

                • 为什么不使用@color 代替fillcolor
                【解决方案12】:

                要更改矢量图像颜色,您可以直接使用 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() 已弃用
                • TextView的drawable***如何使用?
                • getColor(ResId) @David 已弃用,但 getColor(ResId, Theme) 未弃用。或者,如果您不关心主题……或者如果您的上下文/策略委托是一项活动,您可以使用ResourcesCompat.getColor(getResources(), R.color.primary, null);,您可以为最后一个参数使用getTheme()
                【解决方案13】:

                Android Studio 现在支持棒棒糖前的矢量。没有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'
                

                【讨论】:

                • 问题是“如何改变矢量填充颜色”,而不是“如何使用矢量资源”
                【解决方案14】:

                正如在其他答案中所说,不要直接编辑矢量可绘制对象,而是可以在 java 代码中进行着色,如下所示:

                    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 吗?谢谢:)
                • 不,Vicent,根本没有许可证。解决方案非常简单,我猜这里使用的 Builder 模式不是必需的。但是任何人都可以从这个解决方案中受益,并且无需许可即可使用。
                • 很好的答案!完全符合我的需要
                • @VincentD。 SO 网页页脚显示“根据 cc by-sa 3.0 许可的用户贡献,需要注明出处”
                • 它对我进行了一些更改。感谢您的帮助。
                【解决方案15】:

                目前的工作解决方案是 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

                此外,颜色可能会保留在缓存中,因此删除所有用户的应用程序可能会有所帮助。

                【讨论】:

                  【解决方案16】:

                  你可以做到的。

                  但是你不能对颜色使用@color 引用 (..lame),否则它只适用于 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"/>
                  

                  【讨论】:

                  • 这应该是公认的答案! @color 引用在 Lollipop 之前的矢量中不起作用(所以矢量 -> PNG 转换)code.google.com/p/android/issues/detail?id=186431
                  • @color 引用现在可用于所有 Android 版本的 fillColor 属性,但它不支持颜色状态列表。
                  • 看起来向量状态列表的方法是使用AnimatedStateListDrawables
                  • @TheIT 我需要什么才能启用它?似乎不适合我
                  • 直接设置颜色时不起作用。还是白的。
                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2020-01-29
                  • 1970-01-01
                  • 2016-02-13
                  • 2021-10-15
                  相关资源
                  最近更新 更多