SVG学习--VectorDrawable的使用

作者: 皮球二二 | 来源:发表于2016-06-28 17:07 被阅读3790次

    SVG的全称是Scalable Vector Graphics,叫可缩放矢量图形。它和位图(Bitmap)相对,SVG不会像位图一样因为缩放而让图片质量下降。它的优点在于节约空间,使用方便
    Android 5.0中引入了 VectorDrawable 来支持矢量图(SVG),同时还引入了 AnimatedVectorDrawable 来支持矢量图动画,在最近几次Support包更新之后,SVG的兼容性问题得以大大改善
    基于以上所述,是时候了解一下SVG的实现了

    SVG图片的加载

    AS本身就支持SVG的加载,右击drawable,通过Vector Asset直接加载一个SVG图像


    打开SVG选择 选择一张AS自带的SVG图片
    <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:fillColor="#FF000000"
            android:pathData="M19,13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/>
    </vector>
    

    初步解释一下标签的含义
    android:width/android:height: 这个无需多说,这个是整个图片的宽高
    android:viewportWidth/android:viewportHeight: 画布大小。这个值最好与android:width/android:height保持一致,因为android:pathData使用的坐标系范围与他相关。在宽高不会改变的情况下,改变SVG自身内部坐标系的大小,造成图片的偏移与缩放
    android:fillColor: SVG路径的填充色
    android:pathData: SVG路径

    乍一看这个路径描述的内容我们看的一头雾水,我们一步一步来,学习完基本概念,就能很轻松的理解了

    pathData命令

    pathData命令一般由字母跟数字组成,字母多为命令关键字(这里有个大小写的区别,大写的字母是基于原点坐标系的偏移量,即绝对位置;小写字母是基于当前点坐标系的偏移量,即相对位置),数字多为坐标,

    M(x y): 没什么好说的,移动画笔到指定点,并不进行绘制,默认在(0,0)点。与Paint里面moveTo可以理解成一样的概念

    **L(l) (x y) **: 就是直接画一条线了,与它类似的有H(h)跟V(v)。这里有一个方向的概念,pathData中的方向与View绘制的方向是一样的。H就是画一条横线,V就是画一条竖线,L就是画点到点之间的线

    Z: 没有参数,就是连接起点跟终点

    A(rx ry x-axis-rotation large-arc-flag sweep-flag x y): 绘制圆弧。里面的参数比较多,
    rx\ry 是椭圆在X\Y轴的半径
    x-axis-rotation 是X轴旋转角度
    large-arc-flag 0表示取小弧度,1表示取大弧度(这个通过下图可以理解)
    sweep-flag 0表示逆时针方向,1表示顺时针方向

    A(rx ry x-axis-rotation large-arc-flag sweep-flag x y)

    我们继续上一张图看看

    <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:fillColor="@color/colorPrimary"
            android:pathData="M12,12 a4,6 0 1 1 3,4"/>
        <path
            android:fillColor="@android:color/holo_green_light"
            android:pathData="M12,12 a4,6 0 0 1 3,4"/>
        <path
            android:fillColor="@android:color/holo_purple"
            android:pathData="M12,12 a4,6 0 1 0 3,4"/>
        <path
            android:fillColor="@android:color/holo_orange_light"
            android:pathData="M12,12 a4,6 0 0 0 3,4"/>
    </vector>
    

    这里绘制了半径为4dp、6dp的椭圆,椭圆上有2点(12,12)与(15,16),按照大圆弧小圆弧顺逆时针方向4种状态

    A(rx ry x-axis-rotation large-arc-flag sweep-flag x y)

    Q(x1 y1 x y): 二次贝塞尔曲线。在之前的文章里面,我已经说过贝塞尔曲线的概念,如果还不是很了解,请参阅利用属性动画,实现简单的爱心气泡点赞效果一文所涉及到的相关知识。这里(x1, y1)是控制点的坐标,(x,y)是终点坐标。还有一个类似的T指令,他只有终点参数可以设置,他的控制点被默认为上一次的控制点关于上次终点的中心对称点,比如上一次的控制点P1是(6,6),终点P2是(8,10), 那么使用T指令后默认控制点P1`为(10,14)。

    <path android:strokeColor="@android:color/holo_red_dark"
        android:strokeWidth="0.1"
        android:pathData="M12,12 Q 14,14 18,13">
    </path>
    
    Q(x1 y1 x y)

    C(x1 y1 x2 y2 x y): 三次贝塞尔曲线。同二阶一样,前2个坐标为2个控制点的坐标,最后一个为终点坐标。这里还有一个S指令,同T指令功能相同,就是上一次最后一个控制点相对上次的终点的中心对称点

    <path android:strokeColor="@android:color/holo_red_dark"
        android:strokeWidth="0.1"
        android:pathData="M12,12 C 14,14 18,13 20,8">
    </path>
    
    C(x1 y1 x2 y2 x y)

    至此,我们就把SVG涉及到画图的部分学习完了,我们再回过头来看看刚才的drawable是怎么实现的

    +号的实现

    同样是一笔一笔的用L\H\V组合而成

    投机取巧

    给大家一个网址阿里巴巴矢量图标库,这个里面可以下载好web版本的SVG图片,然后我们将其拷贝到Android SVG to VectorDrawable,这样我们就能大致获取到各种素材的SVG图片了

    注意事项

    以上写法在android 5以上是没有任何问题的,但是放到之前版本上就会出现问题,看看之前的圆弧

    Paste_Image.png

    原本是彩色的,在这里变成黑色的了。。。怎么办?

    1 在build.gradle里面进行配置

    android {
        defaultConfig {
            vectorDrawables.useSupportLibrary = true
        }
    |
    

    2 只能用于AppCompatImageView或者AppCompatImageButton或其子类,而且必须在app:srcCompat标签中使用。

    这样是肯定没有问题的,但是问题在于,我不可能把代码里面所有View都改成这2种。。。

    3 SVG图像需要依附于StateListDrawable,InsetDrawable,LayerDrawable,LevelListDrawable,RotateDrawable,这样就可以在低版本中显示了。StateListDrawable最简单,就是直接写一个selector即可

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

    别忘记还有一个标志位要开启,在activity的最上方

    static {
        AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
    }
    

    这样就没问题了

    4 换色
    如果你想手动更换图片的背景色,那么只要这样就可以了

    VectorDrawableCompat a=VectorDrawableCompat.create(getResources(), R.drawable.ic_a, getTheme());
    a.setTint(Color.RED);
    ImageView imageview= (ImageView) findViewById(R.id.imageview);
    imageview.setImageDrawable(a);
    
    Paste_Image.png

    如何手动更换某一部分Path的色值,我暂时还不知道,如果你知道,请告诉我

    参考文章

    Android vector 标签 pathData 详解
    关于android中矢量图如何用,有坑,爬坑,如何替代的另一些看法

    相关文章

      网友评论

      本文标题:SVG学习--VectorDrawable的使用

      本文链接:https://www.haomeiwen.com/subject/amezdttx.html