Android 矢量图详解

官方文档

关于 Vector,在官方开发指南中介绍。本文章是由个人翻译官方指南然后添加个人理解完成。

由于个人精力有限,多个渠道发布,排版上可能会有问题,如果影响查看,请移步 Android 开发者家园

Vector Drawables 概述

VectorDrawable 和 AnimatedVectorDrawable 是在 Android 5.0 系统中第一次加入,当然我们可以使用 Android 的支持库,来支持旧的版本,通过 VectorDrawableCompat 和 AnimateVectorDrawableCompat 来实现。

VectorDrawble 是在 xml 文件中定义的矢量图形。xml 文件中定义的矢量图形,它是一组带有颜色信息的点、线和曲线,使用矢量图主要的优点是图形可伸缩性。可以在不损失显示质量的情况下进行缩放,这意味着我们可以在不同的屏幕密度的手机上使用相同的文件。这样会使 APK 文件变小更加有利于开发人员维护。我们还可以通过多个 XML 文件和矢量图结合用于动画。

既然说起 VectorDrawable 了,那就不得不提 SVG (Scalable Vector Graphic)了,这两个经常混淆,其实 SVG 就是一种基于可扩展语言(xml),用于描述二维矢量图形的一种图形格式(和我们常见的 .png 等等图片一样,都是一种图片格式),它有自己的一套编写规范(使用 XML 编写的),所以这种图片是根据他自己的一套规范通过 XML 语言编写而成的图片。而我们的 VectorDrawable 是编程中的,它仅支持 SVG 规范中有限的内容。Android Studio 支持将 SVG 文件转换成 VectorDrawable 。这就是他们两者的关系。

path 中的常用的简单绘制命令

  • moveto 命令 M 移动到新的位置
  • closepath 命令 Z 封闭路径,从当前的位置画一条直线到该路径或者子路径起始位置
  • lineto 命令 L ,从当前的位置画一条线到指定的位置
  • horizontal lineto 命令 H 水平画一条直线到指定位置
  • vertical lineto 命令 V 垂直画一条直线到指定位置
  • 贝塞尔曲线 命令 Q
  • 光滑二次贝塞尔曲线 命令 T
  • elliptical arc 命令 A 椭圆弧

每个命令都有大小写的形式,大写代表后面的参数是绝对坐标,小写表示相对坐标(我们一般用大写就可以了),参数之间用空格或者逗号隔开。所谓的相对坐标是相对于前面一个点的,比如:M30,0 l 10,10 换算成绝对坐标就是 M30,0 L40,10

命令使用实例

  • M(x y) 移动到坐标 x,y 处
  • Z 后面不接参数,直接连接起点和终点
  • L(x y)直线连接到坐标 x,y 处
  • H(x) 水平连接
  • V(y) 垂直连接
  • C(x1 y1 x2 y2 x y)控制点 x1,y1 x2,y2 终点坐标 x,y
  • Q(x1 y1 x y)控制带点 x1,y1 终点坐标 x ,y;
  • A(rx,ry,x-axis-rotation,large-arc-flag,sweep-flag,x,y);
    • rx,ry 椭圆半径
    • x-axis-rotation x 轴旋转角度
    • large-arc-flag 为 0 的时候表示取小弧度,1 的时候取大弧度
    • sweep-flag 0 取逆时针方向,1 取顺时针方向
    • (x,y) 是终点的坐标

VectorDrawable 如何定义

VectorDrawable 在 drawable 文件夹中通过 来定义,这里先来详细的介绍一下 vector 中的各个属性(和网上的许多不一样,网上的大多都没有自己验证过)

<!--用于定义 vector drawable-->
<vector
        android:name(用于定义这个 vector drawable 的名字)、
        android:width(定义该 drawble 的内部宽度,支持所有的 Android 系统支持的尺寸单位,通常使用 dp)
        android:height(定义该 drawble 的内部高度,支持所有的 Android 系统支持的尺寸单位,通常使用 dp)
        android:viewportWidth(定义矢量图视图的宽度,实际上就是对应 path 路径所使用的数据)
        android:viewportHeight(定义矢量图视图的高度,实际上就是对应 path 路径所使用的数据)
        android:tint(定义该 drawble 线条的颜色,定义了后,你再在路径里面设置颜色就没有作用了)
        android:tintMode(定义 tint 颜色的 Porter-Duff blending 模式,默认值为 src_in,暂时不用理会)
        android:autoMirrored 设置当系统为 RTL (right-to-left)布局的时候,是否自动镜像该图片。
        android:alpha 该图片的透明属性
        >
    <grup
          // 有时候我们需要对几个路径一起处理,这样就可以使用 group 元素来把多个 path 放到一起,group 支持的属性有
          android:name 定义 group 的名字
          android:rotation 定义该 group 的路径旋转多少度(顺时针旋转)
          android:pivotX 定义缩放和旋转该 group 时候的 X 参考点。该值相对于 vector 的 viewport 值来指定的。
          android:pivotY 定义缩放和旋转该 group 时候的 Y 参考点。该值相对于 vector 的 viewport 值来指定的。
          android:scaleX 定义 X 轴的缩放倍数
          android:scaleY 定义 Y 轴的缩放倍数
          android:translateX 定义移动 X 轴的位移。相对于 vector 的 viewport 值来指定的
          android:translateY 定义移动 Y 轴的位移。相对于 vector 的 viewport 值来指定的>
          <path
                // path 元素里面的 pathData 就是矢量图的路径数据,除此之外还可以设置其他的属性。path 的属性有:
                android:name 定义该 path 的名字,这样在其他地方可以通过名字来引用这个路径
                android:pathData 和 SVG 中 d 元素一样的路径信息
                android:fillColor 定义填充路径的颜色,如果没有定义则不填充路径
                android:strokeWidth 定义路径边框的粗细尺寸
                android:strokeAlpha 定义路径边框的透明度
                android:fillAlpha 定义填充路径颜色的透明度
                android:trimPathStart 从路径起始位置(path 的 M 位置)截取后剩下的内容,取值范围从 0 到 1,比如,取值是 0.3 则截取后的内容就是 原长度 - (原长度*0.3)
                android:trimPathEnd 从路径起始位置位置截取的内容,取值范围从 0 到 1,比如,取值是 0.3,则截取后的内容就是 原长度*0.3
                需要注意的是如果 trimPathStart 和 strimPathEnd 一块使用的话,这里有个规律如果 trimPathEnd 取值大于等于 trimPathStart 的时候结果就是他们两者分别截取后内容的交集,如果 trimPathEnd 小于 trimPathStart 的时候,取值就是他们俩的合集(这是经过我无数的实验得出的规律,你也可以尝试一下)
                android:trimPathOffset 其实就是设置开始点的偏移位置(取值 从 0 到 1)1 的话就是开始点和结束的互换了,注意这个路径是可以循环的(下面画图说明)
                android:strokeLineCap 设置路径的线头的形状,取值为 butt,round,square 默认是 butt
                android:strokeLineJoin 设置路径交界处的连接方式,取值为 miter、round、bevel 默认是 miter
                android:strokeMiterLimit 设置斜角的上界 默认是 4 (当 strokeLineJoin 设置为 "miter" 的时候,绘制两条线段以锐角相交的时候,所得的斜面可能相当长,当斜面太长,就会变的不协调。strokeMiterLimit 属性为斜面的长度设置了一个上限。这个属性表示斜面长度和线条长度的比值。当 strokeLineJoin 设置为其他属性时,这个属性是无效的)

        </path>

        vector 还支持 clip-path 元素,定义当前绘制的剪切路径。注意:clip-path 只对当前的 group 和子 group 有效。需要 API 大于等于 21

    </grup>

</vector>

矢量动画

利用 XML 文件来设置矢量动画

  1. 创建一个矢量图

    <?xml version="1.0" encoding="utf-8"?>
    <vector xmlns:android="http://schemas.android.com/apk/res/android"
            android:width="200dp"
            android:height="200dp"
            android:viewportWidth="100"
            android:viewportHeight="100">
        <group android:name="head_eyes">
            <path
                android:fillColor="@color/colorPrimary"
                android:name="head"
                android:pathData=" M50,50 A15,15,0,1,1 50,51Z"
                android:strokeWidth="2"
                android:strokeColor="@color/colorPrimary"/>
            <group android:name="eyes">
                <path android:fillColor="@android:color/white"
                      android:name="eye_left"
                      android:pathData="M55,40A2,2,0,1,1,55,41"/>
                <path android:fillColor="@android:color/white"
                      android:name="eye_right"
                      android:pathData="M69,40A2,2,0,1,1,69,41"/>
            </group>
    
            <path android:fillColor="@color/colorAccent"
                android:pathData="M60,55L55,60H65Z"/>
    
        </group>
    </vector>

哈哈,样子太丑了,大家就凑合着看把。

  1. 在 drawble 创建矢量动画

    目的就是将我们的矢量图和 objectAnimator 关联起来

    <?xml version="1.0" encoding="utf-8"?>
    <animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
        // 对应动画文件
        android:drawable="@drawable/vector_simple">
        <target
            android:animation="@animator/head"
            // 这里的名字对应你的矢量图中想要产生动画的 path 或者 group 或者 clip-path 的名字
            android:name="head_eyes"/>
    
    </animated-vector>
    
  2. 在 animator 中创建动画
    <?xml version="1.0" encoding="utf-8"?>
    <set xmlns:android="http://schemas.android.com/apk/res/android">
        <objectAnimator
            android:duration="200"
            android:propertyName="translateY"
            android:repeatCount="infinite"
            android:repeatMode="reverse"
            android:valueFrom="0"
            android:valueTo="20"
            android:valueType="floatType"/>
    </set>
  3. 布局文件中添加图片
    <ImageView
            android:id="@+id/iv_android"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/animated_head"
            android:contentDescription="@string/app_name"/>
  4. 在程序中启动动画
    Drawable drawable =  ivAndroid.getDrawable();
    ((Animatable)drawable).start();

效果图

在 objectAnimator 的 propertyName 中有两个很重要的属性值,trimPathEndtrimPathStart 表示截取,和前面介绍的 path 里面的类似,利用这个可以绘制 vectordrawble。注意如果动画使用这个两个属性值的话,animated-vector 中 target 对应的 name 必须是 path 类型不能是 group 效果图:

SVG 图片转成 vectordrawble

利用我们 Android Studio 提供的工具就可以将 SVG 格式的图片直接转成我们的 vectordrawble 了。

原文地址:https://www.cnblogs.com/sydmobile/p/10854553.html

时间: 2024-11-05 17:34:19

Android 矢量图详解的相关文章

android屏幕适配详解

android屏幕适配详解 官方地址:http://developer.android.com/guide/practices/screens_support.html 一.关于布局适配建议 1.不要使用绝对布局 2.尽量使用match_parent 而不是fill_parent . 3.能够使用权重的地方尽量使用权重(android:layout_weight) 4.如果是纯色背景,尽量使用android的shape 自定义. 5.如果需要在特定分辨率下适配,可以在res目录上新建layout

Android 四大组件 详解

[置顶] Android四大组件详解 分类: Android四大组件2013-02-09 16:23 19411人阅读 评论(13) 收藏 举报 Android开发 注:本文主要来自网易的一个博主的文章,经过阅读,总结,故留下文章在此 Android四大基本组件介绍与生命周期 Android四大基本组件分别是Activity,Service服务,Content Provider内容提供者,BroadcastReceiver广播接收器. 一:了解四大基本组件 Activity : 应用程序中,一个

Android相机开发详解(一)

Android相机开发详解(一) 请支持原创,尊重原创,转载请注明出处:http://blog.csdn.net/kangweijian(来自kangweijian的csdn博客) Android相机开发能够实现打开相机,前后摄像头切换,摄像预览,保存图片,浏览已拍照图片等相机功能. Android相机开发详解(一)主要实现打开相机,摄像预览,前后置摄像头切换,保存图片等四个功能. Android相机开发详解(二)主要实现翻页浏览相片,触控缩放浏览图片,删除图片,发送图片等四个功能. Andro

Android之canvas详解

首先说一下canvas类: Class Overview The Canvas class holds the "draw" calls. To draw something, you need 4 basic components: A Bitmap to hold the pixels, a Canvas to host the draw calls (writing into the bitmap), a drawing primitive (e.g. Rect, Path, t

Android第三方登录详解2

接着Android第三方登录详解1讲 1.找到友盟  文档中心 2.找到 3.将 UMSocialService mController = UMServiceFactory.getUMSocialService("com.umeng.login");       这句话放到对应activity 弄成全局即可 4QQ 登录 //参数1为当前Activity, 参数2为开发者在QQ互联申请的APP ID,参数3为开发者在QQ互联申请的APP kEY. UMQQSsoHandler qqS

Android Animation动画详解(二): 组合动画特效

前言 上一篇博客Android Animation动画详解(一): 补间动画 我已经为大家介绍了Android补间动画的四种形式,相信读过该博客的兄弟们一起都了解了.如果你还不了解,那点链接过去研读一番,然后再过来跟着我一起学习如何把简单的动画效果组合在一起,做出比较酷炫的动画特效吧. 一. 动画的续播 如题,大家想想,如果一个页面上包含了许多动画,这些动画要求按顺序播放,即一个动画播放完成后,继续播放另一个动画,使得这些动画具有连贯性.那该如何实现呢? 有开发经验或者是逻辑思维的人肯定会想,对

Android进阶——Preference详解之Preference系的基本应用和管理(二)

引言 前面一篇文章Android进阶--Preference详解之初识Preference及Preference系(一)简单描述下了Preference的家族构成和基本知识,相信对于Preference早已不会陌生,肯定也跃跃欲试了吧,这篇文章就给大家总结下Preference.PreferenceActivity.PreferenceGroup.RingtonePreference的普通应用和管理,还有通过一些测试来验证一些机制和原理. 一.PreferenceActivity 1.Prefe

android:ToolBar详解

这篇文章因为是台湾人写的,语言风格很别致.本文在原文的基础上做了一些微调(主要是繁体字的问题). 今年(2014) 的 google i/o 发表令多数人为之一亮的 material design,而 google 也从「google i/o 2014」 开始,大家也陆陆续续地看到其更新的 android app 皆套用了这个设计介面.当然,这个设计介面著实让大家感到惊艳外,更让 android 开发者开始担心未来 app 的界面处理了. 不过,所幸有着之前 actionbar 的经验后,and

Android关键资源详解

Android层次结构中,资源扮演着重要的角色,资源是绑定到可执行程序的文件(例如音乐文件)或值(例如对话框标题).常用的资源实例包括字符串.颜色.布局文件等.例如不需要将字符串硬编码到应用程序中,可以使用它们的ID,这种间接性使你无需要改变源代码就能够更改字符串资源的文本. Android中主要通过两种文件类型来支持资源:XML文件和原始文件(包括图像.音频和视频).甚至在XML文件内部有时也能看到资源被定义为XML文件内部的值(如字符串),有时XML文件整体就是一个资源(如布局资源). XM