31、Android矢量动画

SVG矢量动画

(Bitmap)相对,SVG不会像位图一样因为缩放而让图片质量下降。它的优点在于节约空间,使用方便 。Android 5.0中引入了 VectorDrawable 来支持

矢量图(SVG),同时还引入了 AnimatedVectorDrawable 来支持矢量图动画,在最近几次Support包更新之后,SVG的兼容性问题得以大大改善

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

SVG命令

使用<path>标签创建SVG就像使用指令的方式来控制一只画笔,它所支持的指令有以下几种:

指令 说明
M = moveto(M,X,Y) 将画笔移动到指定坐标位置,但未发生绘制。
L = lineto(L,X,Y) 画直线到指定的坐标位置。
H = horizontal lineto(H X) 画水平线到指定的X坐标位置。
V = vertical lineto(V Y) 画垂直线到指定的Y坐标位置。
C = curveto(C X1,Y1,X2,Y2,ENDX,ENDY) 三次贝塞尔曲线
S = smooth curveto(S X2,Y2,ENDX,ENDY) 三次贝塞尔曲线
Q = quadratic Belzier curve(Q X,Y,ENDX,ENDY) 二次贝塞尔曲线
T = smooth quadratic Belzier curveto(T ENDX,ENDY) 映射前面路径的终点
A = elliptical Arc(A RX,RY,XROTATION,FLAG1,FLAG2,X,Y) 绘制一段弧线,允许弧线不闭合。 1)RX,RY指所在椭圆大小 2)XROTATION椭圆的X轴和水平方向顺时针夹角。 3)FLAG1有两个值,1表示大角度弧线,0为小角度弧线 4)FLAG2有两个值,1位顺时针,0位逆时针 5)X,Y轴为终点坐标
Z = closepath() 关闭路径

在使用上面的指令时,需要注意以下几点:

坐标轴(0,0)为中心,X轴水平向右,Y轴水平向下。
所有指令大小写均可,大写是绝对定位,小写相对定位。
同一个指令出现多次可以只用一个,且指令间的空格可省略。

SVG编辑器

SVG参数的写法固定而且复杂,因此完全可以使用程序来实现,所以一般通过SVG编辑器来编辑SVG图形。网上有很多SVG的在线编辑器,通过可视化编辑好图形后,点击View Source就可以转换为SVG代码。

https://editor.method.ac/

使用SVG

在Android 5.X中提供两个新的api来支持SVG:VectorDrawable(SVG图形) 和 AnimatedVectorDrawable(动画效果)。

  • VectorDrawable
    在res/drawable/ic_verctor_test.xml中创建静态的SVG图形,其中<path>是结构中的最小单位,<group>可以将不同的<path>进行组合。
<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="test"
            android:rotation="0">
            <path
                android:fillColor="@android:color/holo_blue_light"
                android:pathData="M 25 50 a 25,25 0 1,0 50, 0"/>
        </group>
</vector>

由于这里使用fillcolor表示填充,如果想要非填充的则使用:

android:strokeColor="@android:color/holo_blue_light"
android:strokeWidth="2"

效果如下图所示:

  • AnimatedVectorDrawable

    AnimatedVectorDrawable的作用是给VectorDrawable提供动画效果,它可以连接静态的VectorDrawable和动态的ObjectAnimation。

1、在res/drawable/anim_vector.xml中通过<animated-vector>标签声明对AnimatedVectorDrawable的使用,并指定其作用的path和group。

<?xml version="1.0" encoding="utf-8"?>
<animated-vector
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/ic_vector_test">
    <target
        android:name="test"
        android:animation="@animator/anim_path"/>
</animated-vector>

2、对应res/drawable/ic_verctor_test.xml中的vector是静态的VectorDrawable

<?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="test"
        android:rotation="0">
        <path
            android:strokeColor="@android:color/holo_blue_light"
            android:strokeWidth="2"
            android:pathData="M 25 50 a 25,25 0 1,0 50,0"/>
    </group>
</vector>

注意:AnimatorVectorDrawable中的target节点下的name和VectorDrawable中group节点下的name必须保持一致。

3、通过AnimatorVectorDrawable中的target节点下的animation属性引入属性动画(必须是属性动画,否则报错)

<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="4000"
    android:propertyName="rotation"
    android:valueFrom="0"
    android:valueTo="360" />

4、当所有的XML准备好之后,我们就可以直接给一个imageview设置背景

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <ImageView
        android:id="@+id/image"
        android:layout_gravity="center"
        android:layout_width="200dp"
        android:layout_height="200dp"
        android:src="@drawable/anim_vector" />
</LinearLayout>

5、最后,通过ImageView中的src引入AnimatorVectorDrawable文件,然后通过代码进行开启即可。

ImageView imageView = (ImageView) findViewById(R.id.image);
Animatable drawable = (Animatable) imageView.getDrawable();
drawable.start();

运行效果如下图所示:

兼容性

SVG在5.X以上使用是没有任何问题的,但是在低版本就会出现各种问题,可以使用如下方法进行兼容:

兼容低版本

我们的SVG在5.X是没有问题,但是在低版本的话可能出现彩色图片变成黑色的,解决方式如下:

  • 在build.gradle里面进行配置
android {
    defaultConfig {
        vectorDrawables.useSupportLibrary = true
    }
|
  • 只能用于AppCompatImageView或者AppCompatImageButton或其子类,而且必须在app:srcCompat标签中使用。

  • 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);
}

动态换色

如果你想手动更换图片的背景色,那么只要按照如下代码操作即可:

VectorDrawableCompat a=VectorDrawableCompat.create(getResources(), R.drawable.ic_a, getTheme());
a.setTint(Color.RED);
ImageView imageview= (ImageView) findViewById(R.id.imageview);
imageview.setImageDrawable(a);
原文地址:https://www.cnblogs.com/pengjingya/p/14952691.html