【问题标题】:How to change color of vector drawable path on button click如何在按钮单击时更改矢量可绘制路径的颜色
【发布时间】:2016-06-08 02:20:13
【问题描述】:

随着新的 android 支持更新,矢量可绘制对象获得向后兼容性。我有一个带有各种路径的矢量图像。我希望通过单击按钮或基于输入值以编程方式更改路径的颜色。是否可以访问向量路径的名称参数?然后改变颜色。

【问题讨论】:

  • 您可以对整个向量进行着色,但不能对单个路径组件进行着色

标签: android vector vector-graphics android-vectordrawable


【解决方案1】:

整个向量的颜色可以使用 setTint 来改变。

您必须在布局文件中设置 ImageView,如下所示:

<ImageView
    android:id="@+id/myImageView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:tint="@color/my_nice_color"
    android:src="@drawable/ic_my_drawable"
    android:scaleType="fitCenter" />

然后更改图像的颜色:

DrawableCompat.setTint(myImageView.getDrawable(), ContextCompat.getColor(context, R.color.another_nice_color));

注意:如果矢量 drawable 设置为 imageView 作为背景,myImageView.getDrawable() 会给出 nullpointerexception。

【讨论】:

  • 这会将色调设置为整个可绘制对象,而不是矢量可绘制对象的特定路径。
  • android:tint必须在设置android:src后设置
  • Button 怎么样? Button 没有 android:tint
  • 我不知道这个操作的范围,但是我在 Activity 范围有问题;当我替换片段时,色调更改不会无效。我用imageView.setColorFilter解决了我的问题
  • 即使你只有一个路径,色调也会同时改变填充和描边。
【解决方案2】:

正如@Eyal 在这篇文章中所说 https://stackoverflow.com/a/32007436/4969047

不能在运行时更改单个路径的颜色。 查看VectorDrawableCompat 的源代码,按名称公开内部元素的唯一方法是getTargetByName,它存在于VectorDrawableCompat 的内部private 状态类VectorDrawableCompatState 中。

因为它是一个私有包(默认)——你不能使用它(除非你使用reflection)。

【讨论】:

  • @Shubral,您能否详细说明如何使用反射来实现这一目标?这可能需要时间,但会帮助很多人。
【解决方案3】:

检查我对这个问题的回答:https://stackoverflow.com/a/38418049/1335438

关于如何通过使用主题和参数化路径以便能够动态设置它们来管理它是一个好主意。

【讨论】:

    【解决方案4】:

    您可以使用此方法在较低的 API 中更改颜色以更改片段中的矢量颜色

    int myVectorColor = ContextCompat.getColor(getActivity(), R.color.colorBlack);
                        myButton.getIcon().setColorFilter(myVectorColor, PorterDuff.Mode.SRC_IN);
    

    您应该使用 MainActivity.this 代替 getActivity 来更改活动中的矢量颜色

    【讨论】:

    • 问题是关于改变特定元素的颜色,而不是整个drawable。
    【解决方案5】:

    可以在运行时更改单个路径的颜色,而无需使用反射。

    VectorMaster 引入了对矢量可绘制对象的动态控制。使用该库可以动态控制矢量可绘制对象的各个方面(通过 Java 实例)。

    只需在应用的 build.gradle 中添加以下依赖项

    dependencies {
        compile 'com.sdsmdg.harjot:vectormaster:1.0.9'
    }
    

    在你的情况下,你需要一个简单的颜色变化:

    矢量示例:your_vector.xml

    <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:name="outline"
        android:pathData="M20.84,4..."
        android:strokeColor="#5D5D5D"
        android:fillColor="#00000000"
        android:strokeWidth="2"/>
    

    XML

    <com.sdsmdg.harjot.vectormaster.VectorMasterView
        android:id="@+id/your_vector"
        android:layout_width="150dp"
        android:layout_height="150dp"
        app:vector_src="@drawable/your_drawable" />
    

    Java

    VectorMasterView heartVector = (VectorMasterView) 
    findViewById(R.id.your_drawable);
    
    // find the correct path using name
    PathModel outline = heartVector.getPathModelByName("outline");
    
    // set the stroke color
    outline.setStrokeColor(Color.parseColor("#ED4337"));
    
    // set the fill color (if fill color is not set or is TRANSPARENT, then no fill is drawn)
    outline.setFillColor(Color.parseColor("#ED4337"));
    

    来自:https://github.com/harjot-oberai/VectorMaster,获得 MIT 许可。

    您现在可以完全控制矢量绘图。

    【讨论】:

    • 非常好。我的 svg 不使用名称,手动编辑和添加名称是不切实际的。是否可以通过数组中的索引获取路径模型?
    • 您可以,但您至少需要一个组名:包含您的路径的组,例如:GroupModel groupModel = getVectorMasterDrawable().getGroupModelByName("groupName"); ArrayList&lt;PathModel&gt; pathModelArrayList = groupModel.getPathModels();
    • @JeRoll,在设置路径颜色后我有机会得到Drawable,目前我将imageview设置为隐藏并采用drawable = imageView.getDrawable()
    【解决方案6】:

    使用它来更改矢量绘图中的路径颜色

    VectorChildFinder vector = new VectorChildFinder(this, R.drawable.my_vector, imageView);
    
    VectorDrawableCompat.VFullPath path1 = vector.findPathByName("path1");
    path1.setFillColor(Color.RED); 
    

    图书馆在这里:https://github.com/devsideal/VectorChildFinder

    【讨论】:

    • 但不在 Maven 中?
    • 啊,我没有添加 jitpack.io。它现在找到了,干杯!
    • 难道没有办法在没有库的情况下更改 VectorDrawable 中某物的颜色吗?支持库中没有这方面的内容吗?
    • 不,我还没有找到任何方法,我就是用这个。
    • @Deven 我找不到更改组内路径的方法。有什么解决办法吗?
    【解决方案7】:

    有几种方法可以做同样的事情,但这适用于 Vector Drawables 以及 SVG(本地/网络)。

    imageView.setColorFilter(ContextCompat.getColor(context, 
    R.color.headPink), android.graphics.PorterDuff.Mode.SRC_IN);
    

    (将 R.color.headPink 更改为您选择的颜色)

    【讨论】:

    • 问题是关于改变特定元素的颜色,而不是整个drawable。
    【解决方案8】:
    DrawableCompat.setTint(imageView.getDrawable(),ContextCompat.getColor(getApplicationContext(), R.color.colorAccent));
    

    【讨论】: