亲宝软件园·资讯

展开

Android动态使用VectorDrawable过程详解

weixin_43912367 人气:0

接上篇继续,讲解使用动态的VectorDrawable

上篇链接:

Android三种方式生成矢量图之VectorDrawable类使用详解

导言

VectorDrawable有两个优点,一个是缩放不失真,另一个是使PNG的体积,大幅度减小,那么如果仅仅只有这两个优点,其实我是并不需要使用VectorDrawable,或者说,这并不能成为我们使用VectorDrawable的重要原因。

那我们使用它的重要原因是什么呢?

那就是VectorDrawable可以使用动画,使用掌握VectorDrawable使用动画的动态技巧,才是核心之一!!!

案例演示

既然是动态的VectorDrawable,那我们就需要有一个动画的效果文件。

首先,我们创建一个属性动画的目录 res --> 右键new --> Android Resource Directory --> 选择animator–> 点击OK 完成创建

接下来,我们在这目录下,创建一个动画文件。此次我们设置一个平移的动画图形

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

有了动画文件,需要一个目标图形,就是让这个动画效果作用于哪个图片上。

我们选中drawable --> New --> Vector Asset 进行设置,由于此次是演示,所以,随便选择一张

我们要让这个图形,有左右移动的效果。

现在我们目标效果和动画图形都有了,那我们如何才能让他们组合起来呢?

让他们组合起来,我们需要使用一样东西,配置动画粘合剂——animated-vector

animated-vector连接了vector和animated,组成动画

我们在drawable下新建arrow_anim.xml文件

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

drawable属性代表连接的图形vector,animation链接的是动画

那里面的name属性是什么意思呢?,让我们去看静态的VectorDrawable,在path标签中,我们可以给图形设置一个name属性,比如说,我们可以给他命名arrow,这个name属性,就代表了整个path。

<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:name="arrow"
        android:fillColor="#FF000000"
        android:pathData="M9.4,16.6L4.8,12l4.6,-4.6L8,6l-6,6 6,6 1.4,-1.4zM14.6,16.6l4.6,-4.6 -4.6,-4.6L16,6l6,6 -6,6 -1.4,-1.4z"/>
</vector>

既然粘合剂写好了,那我们让他展示出我们的动画效果。回到我们的activity_main.xml文件中,设置一个ImageView

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
    <ImageView
        android:id="@+id/image"
        android:layout_width="100dp"
        android:layout_height="100dp"
        app:srcCompat="@drawable/arrow_anim"/>
</LinearLayout>

设置ImageView的点击效果:

package com.zrc.vectordrawable
import android.graphics.drawable.Animatable
import android.graphics.drawable.Drawable
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import kotlinx.android.synthetic.main.activity_main.*
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        image.setOnClickListener{
            val drawable:Drawable = image.drawable
            if (drawable is Animatable) {
                (drawable as Animatable).start()
            }
        }
    }
}

运行之后点击我们会发现并没有效果,并报了一个Log

05-04 17:25:54.370 3180-3180/com.zrc.vectordrawable W/PropertyValuesHolder: Method setTranslateX() with type float not found on target class class androidx.vectordrawable.graphics.drawable.VectorDrawableCompat$VFullPath

问题解决

那这是什么原因哪?这就是我们使用动态的VectorDrawable,需要注意的第一个重要点。

首先我们打开图像文件arrow.xml,通常情况下,我们只需要使用它的path标签和pathData属性,就可以描绘一个VectorDrawable,但是我们针对这个path标签使用属性动画的时候,就需要注意了,有些属性并不存在于path标签中,那么我们就不能使用属性动画改变它的属性。那我们该如何处理呢?

在VectorDrawable中,Android给我们提供了另外一个标签,叫做group,我们使用他吧path标签包裹起来

<vector xmlns:android="http://schemas.android.com/apk/res/android"
        android:width="24dp"
        android:height="24dp"
        android:viewportWidth="24.0"
        android:viewportHeight="24.0">
    <group>
        <path
            android:name="arrow"
            android:fillColor="#FF000000"
            android:pathData="M9.4,16.6L4.8,12l4.6,-4.6L8,6l-6,6 6,6 1.4,-1.4zM14.6,16.6l4.6,-4.6 -4.6,-4.6L16,6l6,6 -6,6 -1.4,-1.4z"/>
    </group>
</vector>

那这group标签有什么用呢?可以对path进行分组,那我们拆成两个path标签

<vector xmlns:android="http://schemas.android.com/apk/res/android"
        android:width="24dp"
        android:height="24dp"
        android:viewportWidth="24.0"
        android:viewportHeight="24.0">
    <group android:name="left">
        <path
            android:fillColor="#FF000000"
            android:pathData="M9.4,16.6L4.8,12l4.6,-4.6L8,6l-6,6 6,6 1.4,-1.4z"/>
    </group>
    <group  android:name="right">
        <path
            android:fillColor="#FF000000"
            android:pathData="M14.6,16.6l4.6,-4.6 -4.6,-4.6L16,6l6,6 -6,6 -1.4,-1.4z"/>
    </group>
</vector>

这样,我们就把path标签分成了两个,并把name属性,赋值到了group中。

相对应的,我们修改arrow_anim.xml文件:

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

之后运行程序:

这样,我们就实现了左边的动画效果,我们如法炮制,让右边也动起来。

我们在animator文件夹中,添加anim_left.xml文件

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

然后在arrow_anim中加入

<?xml version="1.0" encoding="utf-8"?>
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/ic_code_black_24dp">
    <target
        android:animation="@animator/anim"
        android:name="left"/>
    <target
        android:animation="@animator/anim_right"
        android:name="right"/>
</animated-vector>

运行即可,看效果

ok了,由于是属性动画,可以设置旋转等多种效果。大家可以去随意尝试!!!

加载全部内容

相关教程
猜你喜欢
用户评论