使用Android的VectorDrawable类

介绍

尽管Android不直接支持SVG(可缩放矢量图形),但Lollipop引入了一个名为VectorDrawable的新类,该类允许设计人员和开发人员仅使用代码以类似的方式绘制资产。

在本文中,您将学习如何使用XML文件创建VectorDrawable以及如何在项目中对其进行动画处理。 仅运行Android 5.0或更高版本的设备支持此功能,并且目前尚无支持库实现。 本教程的源文件可以在GitHub上找到。

1.创建矢量可绘制

VectorDrawable和标准SVG图像之间的主要相似之处是两者都是使用路径值绘制的。 在了解SVG路径的同时   绘制超出了本文的范围,可以在W3C网站上找到官方文档。 对于本文,您只需要知道path标记就是绘图发生的地方。 让我们看一下绘制以下图像的SVG文件:

将在代码中绘制的CPU图像

该图像有五个主要部分:

  • CPU主体的正方形,由两个拱形组成
  • 代表CPU电线的四组五行

以下代码将此图像绘制为SVG:

<?xml version="1.0" encoding="utf-8"?>

<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
     width="512px" height="512px" viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve">
<path id="cpu" d="
	M341.087,157.478c7.417,0,13.435,6.018,13.435,13.435v170.174 c0,7.417-6.018,13.435-13.435,13.435H170.913 c-7.417,0-13.435-6.018-13.435-13.435V170.913 c0-7.417,6.018-13.435,13.435-13.435H341.087z
	M390.348,157.478 c0-19.785-16.041-35.826-35.826-35.826H157.479c-19.785,0-35.826,16.041-35.826,35.826v197.043 c0,19.785,16.041,35.826,35.826,35.826h197.043c19.785 0,35.826-16.041,35.826-35.826V157.478z 

	M193.304,408.261V462h-17.913 v-53.739H193.304z 
	M264.957,408.261V462h-17.914v-53.739H264.957z 
	M300.783,408.261V462h-17.914v-53.739H300.783z 
	M229.13,408.261 V462h-17.913v-53.739H229.13z 
	M336.609,408.261V462h-17.914v-53.739H336.609z

	M193.304,50v53.739h-17.913V50H193.304z
	M264.957,50 v53.739h-17.914V50H264.957z
	M300.783,50v53.739h-17.914V50H300.783z
	M229.13,50v53.739h-17.913V50H229.13z
	M336.609,50v53.739 h-17.914V50H336.609z

	M408.261,318.695H462v17.914h-53.739V318.695z
	M408.261,247.043H462v17.914h-53.739V247.043z
	M408.261,211.217 H462v17.913h-53.739V211.217z
	M408.261,282.869H462v17.914h-53.739V282.869z
	M408.261,175.391H462v17.913h-53.739V175.391z

	M50,318.695h53.739v17.914H50V318.695z 
	M50,247.043h53.739v17.914H50V247.043z 
	M50,211.217h53.739v17.913H50V211.217z 
	M50,282.869 h53.739v17.914H50V282.869z 
	M50,175.391h53.739v17.913H50V175.391z" />
</svg>

尽管这看起来有些让人不知所措,但实际上您并不需要完全了解如何绘制所有内容以在代码中实现VectorDrawable 。 但是,应该注意的是,为了便于阅读,我在代码中将这五个部分中的每一个都分成了自己的唯一块。

顶部由两个拱形组成,用于绘制圆角正方形,随后的部分分别代表底部,顶部,右侧和左侧的线组。 要将SVG代码转换为VectorDrawable ,首先需要在XML中定义vector对象。 下面的代码来自本文的示例代码中的vector_drawable_cpu.xml文件。

<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:height="64dp"
    android:width="64dp"
    android:viewportHeight="600"
    android:viewportWidth="600" >
    
</vector>

接下来,您可以添加路径数据。 以下代码分为五个不同的路径标签,而不是一个大路径。

<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:height="64dp"
    android:width="64dp"
    android:viewportHeight="600"
    android:viewportWidth="600" >

        <path
            android:name="cpu"
            android:fillColor="#000000"
            android:pathData="
                M341.087,157.478 c7.417,0,13.435,6.018,13.435,13.435 v170.174c0,7.417-6.018,13.435-13.435,13.435 H170.913 c-7.417,0-13.435-6.018-13.435-13.435V170.913c0-7.417,6.018-13.435,13.435-13.435H341.087z
                M390.348,157.478 c0-19.785-16.041-35.826-35.826-35.826H157.479c-19.785,0-35.826,16.041-35.826,35.826v197.043 c0,19.785,16.041,35.826,35.826,35.826h197.043c19.785,0,35.826-16.041,35.826-35.826V157.478z"
        />

        <path
            android:name="wires_bottom"
            android:fillColor="#000000"
            android:pathData="
                M193.304,408.261V462h-17.913 v-53.739H193.304z
                M264.957,408.261V462h-17.914v-53.739H264.957z
                M300.783,408.261V462h-17.914v-53.739H300.783z
                M229.13,408.261 V462h-17.913v-53.739H229.13z
                M336.609,408.261V462h-17.914v-53.739H336.609z"
        />

        <path
            android:name="wires_top"
            android:fillColor="#000000"
            android:pathData="
                M193.304,50v53.739h-17.913V50H193.304z
                M264.957,50 v53.739h-17.914V50H264.957z
                M300.783,50v53.739h-17.914V50H300.783z
                M229.13,50v53.739h-17.913V50H229.13z
                M336.609,50v53.739 h-17.914V50H336.609z" 
        />

        <path
            android:name="wires_right"
            android:fillColor="#000000"
            android:pathData="
                M408.261,318.695H462v17.914h-53.739V318.695z
                M408.261,247.043H462v17.914h-53.739V247.043z
                M408.261,211.217 H462v17.913h-53.739V211.217z
                M408.261,282.869H462v17.914h-53.739V282.869z
                M408.261,175.391H462v17.913h-53.739V175.391z" 
        />
        
        <path
            android:name="wires_left"
            android:fillColor="#000000"
            android:pathData="
                M50,318.695h53.739v17.914H50V318.695z
                M50,247.043h53.739v17.914H50V247.043z
                M50,211.217h53.739v17.913H50V211.217z
                M50,282.869 h53.739v17.914H50V282.869z
                M50,175.391h53.739v17.913H50V175.391z" 
        />

</vector>

如您所见,每个路径部分仅使用pathData属性进行绘制。 现在,您可以将VectorDrawable XML文件作为可绘制的文件包含在标准ImageView ,并且可以缩放到您的应用所需的任何大小,而无需使用任何Java代码。

2.动画矢量绘图

既然您知道如何仅使用代码来创建图像,那么现在就可以开始一些有趣的事情了,并为其赋予动画效果。 在下面的动画中,您会注意到每组电线都向着和远离CPU跳动。

动画VectorDrawables的示例

为了实现此效果,您需要将要设置动画的每个部分包装在<group>标记中。 然后, vector_drawable_cpu.xml的更新版本如下所示:

<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:height="64dp"
    android:width="64dp"
    android:viewportHeight="600"
    android:viewportWidth="600" >

    <group
        android:name="cpu_box">
        <path
            android:name="cpu"
            android:fillColor="#000000"
            android:pathData="
            M341.087,157.478 c7.417,0,13.435,6.018,13.435,13.435 v170.174c0,7.417-6.018,13.435-13.435,13.435 H170.913 c-7.417,0-13.435-6.018-13.435-13.435V170.913c0-7.417,6.018-13.435,13.435-13.435H341.087z
            M390.348,157.478 c0-19.785-16.041-35.826-35.826-35.826H157.479c-19.785,0-35.826,16.041-35.826,35.826v197.043 c0,19.785,16.041,35.826,35.826,35.826h197.043c19.785,0,35.826-16.041,35.826-35.826V157.478z "/>
    </group>
    <group
        android:name="bottom">
        <path
            android:name="wires_bottom"
            android:fillColor="#000000"
            android:pathData="
        M193.304,408.261V462h-17.913 v-53.739H193.304z
        M264.957,408.261V462h-17.914v-53.739H264.957z
        M300.783,408.261V462h-17.914v-53.739H300.783z
        M229.13,408.261 V462h-17.913v-53.739H229.13z
        M336.609,408.261V462h-17.914v-53.739H336.609z" />
    </group>
    <group android:name="top">
        <path
            android:name="wires_top"
            android:fillColor="#000000"
            android:pathData="
        M193.304,50v53.739h-17.913V50H193.304z
        M264.957,50 v53.739h-17.914V50H264.957z
        M300.783,50v53.739h-17.914V50H300.783z
        M229.13,50v53.739h-17.913V50H229.13z
        M336.609,50v53.739 h-17.914V50H336.609z " />
    </group>
    <group android:name="right">
        <path
            android:name="wires_right"
            android:fillColor="#000000"
            android:pathData="
        M408.261,318.695H462v17.914h-53.739V318.695z
        M408.261,247.043H462v17.914h-53.739V247.043z
        M408.261,211.217 H462v17.913h-53.739V211.217z
        M408.261,282.869H462v17.914h-53.739V282.869z
        M408.261,175.391H462v17.913h-53.739V175.391z" />
    </group>
    <group android:name="left">
        <path
            android:name="wires_left"
            android:fillColor="#000000"
            android:pathData="
        M50,318.695h53.739v17.914H50V318.695z
        M50,247.043h53.739v17.914H50V247.043z
        M50,211.217h53.739v17.913H50V211.217z
        M50,282.869 h53.739v17.914H50V282.869z
        M50,175.391h53.739v17.913H50V175.391z" />
    </group>

</vector>

接下来,您将要为每种动画类型创建动画师 。 在这种情况下,每组电线有一个,总共四根。 下面是最上面一组动画的一个示例,下面,左边和右边也需要一个动画。 每个动画师XML文件都可以在示例代码中找到。

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <objectAnimator
        android:propertyName="translateY"
        android:valueType="floatType"
        android:valueFrom="0"
        android:valueTo="-10"
        android:repeatMode="reverse"
        android:repeatCount="infinite"
        android:duration="250" />
</set>

如您所见, propertyName设置为translateY ,这意味着动画将沿Y轴移动。 valueFromvalueTo控制开始和结束位置。 通过将repeatMode设置为reverse并将repeatCount设置为infinite ,只要VectorDrawable可见,动画将永远循环VectorDrawable 。 动画的duration设置为250 ,即以毫秒为单位的时间。

要将动画应用于可绘制文件,您将需要创建一个新的animated-vector XML文件,以将动画制作者与VectorDrawable组相关联。 以下代码用于创建animation_cpu.xml文件。

<?xml version="1.0" encoding="utf-8"?>
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/vector_drawable_cpu">

    <target
        android:animation="@animator/pulse_top"
        android:name="top" />

    <target
        android:animation="@animator/pulse_right"
        android:name="right" />

    <target
        android:animation="@animator/pulse_left"
        android:name="left" />

    <target
        android:animation="@animator/pulse_bottom"
        android:name="bottom" />
</animated-vector>

当所有XML准备就绪时,您可以使用 animation_cpu.xml  ImageView可绘制以显示它。

<ImageView
    android:id="@+id/cpu"
    android:layout_width="64dp"
    android:layout_height="64dp"
    android:src="@drawable/animated_cpu" />

要开始动画,您需要从ImageView获取Animatable的实例,然后调用start

ImageView mCpuImageView = (ImageView) findViewById( R.id.cpu );
Drawable drawable = mCpuImageView.getDrawable();
if (drawable instanceof Animatable) {
    ((Animatable) drawable).start();
}

之后start被调用,在CPU图像上的电线将开始与所用很小的Java代码的移动。

3.转换矢量可绘制对象

VectorDrawable常见用例是将一个图像转换为另一个图像,例如从汉堡包图标变为箭头的操作栏图标。 为此,源路径和目标路径都必须遵循相同的元素数量格式。 在本例中,我们将定义为字符串的左右箭头。

<string name="left_arrow">M300,70 l 0,70 -70,-70 0,0 70,-70z</string>
<string name="right_arrow">M300,70 l 0,-70 70,70 0,0 -70,70z</string>

接下来,您将需要使用left_arrow的路径为箭头创建初始可绘制对象 。 在示例代码中,它称为vector_drawable_left_arrow.xml

<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:height="64dp"
    android:width="64dp"
    android:viewportHeight="600"
    android:viewportWidth="600" >

    <path
        android:name="left_arrow"
        android:fillColor="#000000"
        android:pathData="@string/left_arrow"/>
</vector>

CPU动画和转换之间的主要区别在于animator_left_right_arrow.xml文件。

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">

    <objectAnimator
        android:duration="1000"
        android:propertyName="pathData"
        android:valueFrom="@string/left_arrow"
        android:valueTo="@string/right_arrow"
        android:valueType="pathType"
        android:repeatMode="reverse"
        android:repeatCount="-1"/>

</set>

您会注意到valueFromvalueTo属性引用了左右箭头的路径数据,其中valueType设置为pathTypepropertyName   设置为pathData 。 设置这些后,动画师将知道将一组路径数据更改为另一组。 动画制作完成后,您需要使用新的animated-vector对象将VectorDrawableobjectAnimator关联。

<?xml version="1.0" encoding="utf-8"?>
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/vector_drawable_left_arrow">

    <target
        android:name="left_arrow"
        android:animation="@animator/animator_left_right_arrows" />
</animated-vector>

最后,您只需要将动画的可绘制对象与ImageView关联,然后在Java代码中启动动画。

<ImageView
    android:id="@+id/left_right_arrow"
    android:layout_width="64dp"
    android:layout_height="64dp"
    android:layout_below="@+id/cpu"
    android:src="@drawable/animated_arrow" />
mArrowImageView = (ImageView) findViewById( R.id.left_right_arrow );
drawable = mArrowImageView.getDrawable();
if (drawable instanceof Animatable) {
    ((Animatable) drawable).start();
}

结论

如您所见, VectorDrawable类的使用非常简单,并且允许进行大量自定义以添加简单的动画。 虽然VectorDrawable类目前仅适用于运行Android 5.0及更高版本的设备,但由于更多设备支持Lollipop和将来的Android版本,它们将具有不可估量的价值。

翻译自: https://code.tutsplus.com/articles/using-androids-vectordrawable-class--cms-23948

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值