渐变颜色(GradientColor)能否仅通过XML定义来为填充或描边定义渐变?

34
我在查看 GradientColor 的文档 https://developer.android.com/reference/android/R.styleable.html#GradientColor 。我该如何在 XML 中定义渐变色并将其应用到 XML 矢量图形中?我尝试过在 color.xml、styles.xml 和 XML 矢量图形中定义,但是出现了“无法将 @id/gradclor 转换为 ColorStateList”错误。
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="120dp"
    android:height="120dp"
    android:viewportWidth="120.0"
    android:viewportHeight="120.0">

    <path
        android:name="play_triangle"
        android:pathData="M 30 30 L 30 90 L 80 60 z"
        android:strokeColor="@id/gradclor"
        android:strokeWidth="5"/>

    <color
        android:name="@+id/gradclor"
        android:startColor="#FFFFFF"
        android:endColor="#00FFFF"
        android:angle="145"/>

</vector>

当使用时出现“无法将#FFFFFFFF#00FFFFFF 145转换为ColorStateList”错误。
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="120dp"
    android:height="120dp"
    android:viewportWidth="120.0"
    android:viewportHeight="120.0">

    <path
        android:name="play_triangle"
        android:pathData="M 30 30 L 30 90 L 80 60 z"
        android:strokeColor="@color/GradientStrokeBorder"
        android:strokeWidth="5"/>

</vector>

使用以下颜色.xml文件:

<color name="GradientStrokeBorder">
    <item name="android:startColor">#FFFFFF</item>
    <item name="android:endColor">#00FFFF</item>
    <item name="android:angle">145</item>
</color>
3个回答

54

我终于让它正常工作了。渐变色功能在 Android Studio(当前版本为 2.2)中尚未得到支持,因此无法帮助您进行自动完成,但会将渐变标记标记为错误。尽管如此,该功能确实有效,我已经在 Nexus 5X / API 24 上成功测试过了。当然,您必须使用 API 24+ 设备,否则该功能将不受操作系统支持。

首先,您需要添加像这样的颜色资源文件:

<?xml version="1.0" encoding="utf-8"?>
<gradient xmlns:android="http://schemas.android.com/apk/res/android"
    android:startColor="#FFFFFF"
    android:centerColor="#0000FF"
    android:endColor="#00FFFF"
    android:angle="145"
    android:startX="30"
    android:endX="70"
    android:startY="30"
    android:endY="70"
    android:type="linear"/>
请注意start/end参数,我发现它们对于矢量渐变非常重要。 将此文件放置在res/color文件夹下,并指定一个名称。我已经将其命名为gradient.xml,因此完整路径为res/color/gradient.xml。之后,您可以在颜色属性中引用此资源,包括矢量路径颜色。
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="120dp"
    android:height="120dp"
    android:viewportWidth="120.0"
    android:viewportHeight="120.0">

    <path
        android:name="play_triangle"
        android:pathData="M 30 30 L 30 90 L 80 60 z"
        android:strokeWidth="10"
        android:strokeColor="@color/gradient"/>

</vector>

注意strokeColor中对渐变色资源的引用。希望这可以帮到您!


16
好的。值得一提的是,在API 24(7.0)以下的设备上,这会导致应用程序崩溃,所以我在res/drawable-v24中放了一个引用渐变颜色的版本(res/color/blue_gradient.xml(@color/blue_gradient)),并在res/drawable中放了一个引用常规颜色的版本。 - TTransmit
3
我遇到了这个问题:“必须声明元素梯度”。 - Mobikul Webkul
@MobikulWebkul 相同的问题。你找到解决方案了吗? - marcorei
2
自从这个答案以来,矢量可绘制的向后兼容性得到了提高。vectorDrawables.useSupportLibrary = true会将矢量可绘制转换为API 24以下的PNG格式。需要在文件中嵌入梯度,颜色和尺寸而不使用引用。然后您必须使用app:srcCompat来引用可绘制的对象。对于API 21以下的版本,在您的活动 onCreate 中也需要AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);。https://developer.android.com/guide/topics/graphics/vector-drawable-resources#vector-drawables-backward-solution - TTransmit
起始和结束参数是用来做什么的?我真的无法理解! - distante

26

最新的Android预览版(3.1 Canary 6)包含一个使用渐变矢量资源的示例。

<vector xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:aapt="http://schemas.android.com/aapt"
    android:width="108dp"
    android:height="108dp"
    android:viewportHeight="108"
    android:viewportWidth="108">
    <path
        android:fillType="evenOdd"
        android:pathData="M32,64C32,64 38.39,52.99 44.13,50.95C51.37,48.37 70.14,49.57 70.14,49.57L108.26,87.69L108,109.01L75.97,107.97L32,64Z"
        android:strokeColor="#00000000"
        android:strokeWidth="1">
        <aapt:attr name="android:fillColor">
            <gradient
                android:endX="78.5885"
                android:endY="90.9159"
                android:startX="48.7653"
                android:startY="61.0927"
                android:type="linear">
                <item
                    android:color="#44000000"
                    android:offset="0.0" />
                <item
                    android:color="#00000000"
                    android:offset="1.0" />
            </gradient>
        </aapt:attr>
    </path>
    <path
        android:fillColor="#FFFFFF"
        android:fillType="nonZero"
        android:pathData="M66.94,46.02L66.94,46.02C72.44,50.07 76,56.61 76,64L32,64C32,56.61 35.56,50.11 40.98,46.06L36.18,41.19C35.45,40.45 35.45,39.3 36.18,38.56C36.91,37.81 38.05,37.81 38.78,38.56L44.25,44.05C47.18,42.57 50.48,41.71 54,41.71C57.48,41.71 60.78,42.57 63.68,44.05L69.11,38.56C69.84,37.81 70.98,37.81 71.71,38.56C72.44,39.3 72.44,40.45 71.71,41.19L66.94,46.02ZM62.94,56.92C64.08,56.92 65,56.01 65,54.88C65,53.76 64.08,52.85 62.94,52.85C61.8,52.85 60.88,53.76 60.88,54.88C60.88,56.01 61.8,56.92 62.94,56.92ZM45.06,56.92C46.2,56.92 47.13,56.01 47.13,54.88C47.13,53.76 46.2,52.85 45.06,52.85C43.92,52.85 43,53.76 43,54.88C43,56.01 43.92,56.92 45.06,56.92Z"
        android:strokeColor="#00000000"
        android:strokeWidth="1" />
</vector>

这似乎在Android 6.0+上出现问题(我收到了InflateException)。 - tom808

3

我不确定这个,但根据这个文档

android:strokeColor 指定用于绘制路径轮廓的颜色。可以是颜色或SDK 24+的颜色状态列表或渐变颜色(请参阅GradientColor和GradientColorItem)。如果此属性被动画化,则任何由动画设置的值都将覆盖原始值。如果未指定此属性,则不会绘制任何路径轮廓。

如果您的SDK<24,则应该只使用一种颜色。

另一方面,如果您的SDK大于24,则最好使用<gradient/>来填充您的路径,而不是<color/>


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接