专栏名称: Android_开发者
目录
相关文章推荐
51好读  ›  专栏  ›  Android_开发者

[译] 绘制路径:Android 中矢量图渲染

Android_开发者  · 掘金  · android  · 2019-04-18 05:53

正文

阅读 69

[译] 绘制路径:Android 中矢量图渲染

插图来自 Virginia Poltrack

在上一篇文章中,我们研究了 Android 的 VectorDrawable 格式,了解了它的优点和功能。

我们讨论了如何定义组成 assets 中形状的路径。 VectorDrawable 支持许多实际绘制这些形状的方法,我们可以使用这些方法创建丰富的、灵活的、可配置主题的和可交互的资源。在这篇文章中,我将深入探讨这些技巧:颜色资源、主题颜色、颜色状态列表和渐变的使用。

简单的颜色

绘制路径最简单的方法是指定一种硬编码的 fill/stroke 颜色。

<!-- Copyright 2018 Google LLC.
     SPDX-License-Identifier: Apache-2.0 -->
<vector ...>

    <path
      android:pathData="..."
      android:fillColor="#ff00ff"
      android:strokeColor="#999"
      android:strokeWidth="2"
      android:strokeLineCap="square" />

</vector>
复制代码

你可以定义这两个属性中的一个或者两个,但每个路径只能应用一组 fill/stroke (这与某些图形包不同)。首先绘制填充内容,然后绘制描边内容。描边总是居中的(不像一些图形应用程序定义了内边缘和外边缘),它需要被明确的指定 strokeWidth 属性,而 strokeLineCap strokeLineJoin 属性是可以选择性定义的,这些属性控制描边线的端点/连接处的形状(也可以定义 strokeMiterLimit 来控制 miter 线的交点的形状)。不支持虚线描边。

填充和描边都提供单独的 alpha 属性: fillAlpha strokeAlpha [0-1] 都默认为 1,即完全不透明。如果为一个设置了 alpha 值的组件指定 fillColor strokeColor ,结果是这两个值的结合。例如,如果指定 50% 透明的红色 fillColor #80ff0000 )和 0.5 的 fillAlpha ,那么结果将是 25% 透明的红色。单独的 alpha 属性使路径的不透明度更容易动画化。

颜色资源

矢量图形中填充和描边颜色的设置都支持 @color 资源的语法:

<!-- Copyright 2018 Google LLC.
     SPDX-License-Identifier: Apache-2.0 -->
<vector ...>

  <path
    android:pathData="..."
    android:fillColor="@color/teal"
    android:strokeColor="@color/purple"
    android:strokeWidth="2" />

</vector>
复制代码

这允许你可以提取颜色以便于维护,并帮助你约束应用程序的色调一致性。

它还允许你使用 Android 的 资源限定符 在不同配置中提供不同的颜色值。例如,你可以在夜间模式( res/colors-night/colors.xml )或如果 设备支持宽色域 res/colors-widecg/colors.xml )下提供替代的颜色值。

主题色

所有版本的矢量(从 API14 到 AndroidX)都支持使用主题属性(例如 ?attr/colorPrimary )来指定颜色。这些颜色是由主题提供的,对于创建灵活的资源非常有用,这种资源可以在应用的不同位置使用。

使用主题颜色主要有两种方式。

为 fills/strokes 设置主题色

你可以直接引用主题颜色来设置填充或描边路径:

<!-- Copyright 2018 Google LLC.
     SPDX-License-Identifier: Apache-2.0 -->
<vector ...>

  <path
    android:pathData="..."
    android:fillColor="?attr/colorPrimary" />

</vector>
复制代码

如果你希望资源中的元素依据主题有所不同,那么这是非常有用的。例如,一个体育类型的应用程序可以设置一个主题色的占位符图像来显示球队的颜色;使用单一绘图:

用主题颜色填充路径

着色

<vector> 根元素提供了 tint tintMode 属性值:

<!-- Copyright 2018 Google LLC.
     SPDX-License-Identifier: Apache-2.0 -->
<vector ...
  android:tint="?attr/colorControlNormal">

    <path ... />

</vector>
复制代码

虽然你可以使用它来采取静态着色,但它在与主题属性组合时更有用。这允许您根据引入的主题更改整个资源文件的颜色。例如,你可以使用 ?attr/colorControlNormal ,它定义了图标的标准颜色,并在明暗主题之间变化。这样你就可以在不同主题的屏幕上使用一个图标:

在明/暗屏幕上对图标进行着色,使其具有适当的颜色

使用着色的一个好处是,你不需要依赖于你的资源文件(通常来自你的设计师)是正确的颜色。对图标使用 ?attr/colorControlNormal 属性既能主题化,又能保证资源文件的颜色完全相同、正确。

tintMode 属性允许你更改用于着色绘制的混合模式,它支持: add multiply screen src_atop src_over src_in ;对应于类似的 PorterDuff.Mode 。通常你使用的默认属性是 src_in ,它将图像作为 alpha 蒙版应用于整个图标,忽略单个路径中的任何颜色信息(尽管 alpha 通道是维护的)。因此,如果你打算给图标着色,那么最好使用完全不透明的填充/描边颜色(惯例是使用 #fff )。

你可能想知道什么时候为资源着色?什么时候在单独的路径上使用主题颜色?因为这两种颜色都可以获得类似的结果。如果你只想在某些路径上使用主题颜色,那么必须直接使用它们。另一个需要考虑的问题是,你的资源是否具有重叠渲染。如果是这样的话,那么用半透明的主题颜色填充可能不会产生你想要的效果,但应用着色模式可能达到这种效果。

具有重叠路径和半透明主题颜色的资源:比较着色和填充模式

请注意,你可以通过设置 android:theme 属性,在 Activity / View 级别改变可绘制对象的主题,或者在代码中使用 ContextThemeWrapper 设置一个特定的主题来 填充 这个矢量图形。

/* Copyright 2018 Google LLC.
   SPDX-License-Identifier: Apache-2.0 */
val themedContext = ContextThemeWrapper(context, R.style.baz)
val drawable = AppCompatResources.getDrawable(themedContext, R.drawable.vector)
复制代码

覆盖主题 baz

颜色状态列表

对于 填充/描边, VectorDrawable 支持 ColorStateLists 的引用。通过这种方式,你可以创建一个单独的绘图,其中路径根据视图/绘图的状态(如按下、选择、激活等)来改变颜色。

矢量图形对按下和选择的状态作出响应的例子

这是在 API24 中引入的,但最近添加到 AndroidX 中,从 1.0.0 版本也支持 API14。这也使用了 AndroidX 颜色状态列表填充 ,这意味着你也可以在 ColorStateList 中使用主题属性和 alpha(它们本身只在 API23 中被添加到平台中)。







请到「今天看啥」查看全文