动画化可绘制图形

尝试 Compose 方法
Jetpack Compose 是 Android 推荐的 UI 工具包。了解如何在 Compose 中使用动画。
图 1. 可绘制对象的动画。

在某些情况下,需要对图像进行动画处理。如果您想显示由多个图像组成的自定义加载动画,或者您希望在用户操作后图标变形,这将非常有用。Android 提供了两种动画化可绘制对象的方法。

第一种方法是使用 AnimationDrawable。这使您可以指定几个静态的 可绘制文件,这些文件一次显示一个以创建动画。第二种方法是使用 AnimatedVectorDrawable,它允许您对 矢量可绘制对象 的属性进行动画处理。

使用 AnimationDrawable

创建动画的一种方法是加载一系列可绘制资源,例如胶片卷。 AnimationDrawable 是此类可绘制对象动画的基础。

您可以使用 AnimationDrawable 类 API 在代码中定义动画的帧,但使用单个 XML 文件定义它们更容易,该文件列出了构成动画的帧。此类动画的 XML 文件位于 Android 项目的 res/drawable/ 目录中。在这种情况下,说明提供了动画中每个帧的顺序和持续时间。

XML 文件由 <animation-list> 元素作为根节点和一系列子 <item> 节点组成,每个节点定义一个帧——一个可绘制资源及其持续时间。以下是 Drawable 动画的 XML 文件示例

<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
    android:oneshot="true">
    <item android:drawable="@drawable/rocket_thrust1" android:duration="200" />
    <item android:drawable="@drawable/rocket_thrust2" android:duration="200" />
    <item android:drawable="@drawable/rocket_thrust3" android:duration="200" />
</animation-list>

此动画运行三帧。将列表的 android:oneshot 属性设置为 true 将使其循环一次,然后停止并在最后一帧保持。如果您将 android:oneshot 设置为 false,则动画将循环。

如果您将此 XML 另存为项目 res/drawable/ 目录中的 rocket_thrust.xml,则可以将其作为背景图像添加到 View 中,然后调用 start() 以使其播放。以下是活动示例,其中动画添加到 ImageView 中,然后在触摸屏幕时进行动画处理

Kotlin

private lateinit var rocketAnimation: AnimationDrawable

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.main)

    val rocketImage = findViewById<ImageView>(R.id.rocket_image).apply {
        setBackgroundResource(R.drawable.rocket_thrust)
        rocketAnimation = background as AnimationDrawable
    }

    rocketImage.setOnClickListener({ rocketAnimation.start() })
}

Java

AnimationDrawable rocketAnimation;

public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);

  ImageView rocketImage = (ImageView) findViewById(R.id.rocket_image);
  rocketImage.setBackgroundResource(R.drawable.rocket_thrust);
  rocketAnimation = (AnimationDrawable) rocketImage.getBackground();

  rocketImage.setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View view) {
        rocketAnimation.start();
      }
  });
}

需要注意的是,在您的 ActivityonCreate() 方法期间,不能调用在 AnimationDrawable 上调用的 start() 方法,因为 AnimationDrawable 尚未完全附加到窗口。要立即播放动画,无需交互,您可以从您的 Activity 中的 onStart() 方法调用它,该方法在 Android 将视图显示在屏幕上时调用。

有关 XML 语法以及可用标签和属性的更多信息,请参阅 动画资源

使用 AnimatedVectorDrawable

矢量可绘制对象 是一种可缩放的可绘制对象类型,缩放后不会出现像素化或模糊。 AnimatedVectorDrawable——以及 AnimatedVectorDrawableCompat 用于向后兼容——允许您对矢量可绘制对象的属性进行动画处理,例如旋转它或更改路径数据以将其变形为不同的图像。

您通常在三个 XML 文件中定义动画矢量可绘制对象

  • res/drawable/ 中包含 <vector> 元素的矢量可绘制对象。
  • res/drawable/ 中包含 <animated-vector> 元素的动画矢量可绘制对象。
  • 一个或多个在 res/animator/ 中包含 <objectAnimator> 元素的对象动画器。

动画矢量可绘制对象可以对 <group><path> 元素的属性进行动画处理。 <group> 元素定义一组路径或子组,而 <path> 元素定义要绘制的路径。

当您定义要进行动画处理的矢量可绘制对象时,请使用 android:name 属性为组和路径分配唯一的名称,以便您可以从动画器定义中引用它们。例如

res/drawable/vectordrawable.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="rotationGroup"
        android:pivotX="300.0"
        android:pivotY="300.0"
        android:rotation="45.0" >
        <path
            android:name="v"
            android:fillColor="#000000"
            android:pathData="M300,70 l 0,-70 70,70 0,0 -70,70z" />
    </group>
</vector>

动画矢量可绘制对象定义通过其名称引用矢量可绘制对象中的组和路径

res/drawable/animatorvectordrawable.xml

<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
  android:drawable="@drawable/vectordrawable" >
    <target
        android:name="rotationGroup"
        android:animation="@animator/rotation" />
    <target
        android:name="v"
        android:animation="@animator/path_morph" />
</animated-vector>

动画定义表示 ObjectAnimatorAnimatorSet 对象。此示例中的第一个动画器将目标组旋转 360 度

res/animator/rotation.xml

<objectAnimator
    android:duration="6000"
    android:propertyName="rotation"
    android:valueFrom="0"
    android:valueTo="360" />

此示例中的第二个动画器将矢量可绘制对象的路径从一种形状变形为另一种形状。路径必须兼容变形:它们必须具有相同数量的命令,并且每个命令的参数数量相同。

res/animator/path_morph.xml

<set xmlns:android="http://schemas.android.com/apk/res/android">
    <objectAnimator
        android:duration="3000"
        android:propertyName="pathData"
        android:valueFrom="M300,70 l 0,-70 70,70 0,0   -70,70z"
        android:valueTo="M300,70 l 0,-70 70,0  0,140 -70,0 z"
        android:valueType="pathType" />
</set>

以下是生成的 AnimatedVectorDrawable

图 2. AnimatedVectorDrawable

动画矢量可绘制对象 (AVD) 预览

Android Studio 中的动画矢量可绘制对象工具允许您预览动画可绘制资源。此工具可帮助您在 Android Studio 中预览 <animation-list><animated-vector><animated-selector> 资源,并使微调自定义动画变得更容易。

User previewing and playing an animation inside Android Studio
图 3. Android Studio 中的动画矢量可绘制对象工具。

有关更多信息,请参阅 AnimatedVectorDrawable 的 API 参考。