使用动画移动视图

屏幕上的对象通常由于用户互动或 在后台进行处理。不要立即更新对象的 从而使其从一个区域闪烁到另一个区域,请使用动画 请将其从起始位置移至结束位置。

Android 支持在屏幕上重新定位视图对象,一种方式是: 使用 ObjectAnimator。您提供结束位置 以及动画持续时间。您可以 还使用时间插值器来控制 动画。

使用 ObjectAnimator 更改视图位置

ObjectAnimator API 提供了一种方法来更改具有指定时长的视图属性。 它包含用于创建 ObjectAnimator 实例的静态方法,具体取决于 您要为哪种类型的属性添加动画效果:将视图位置调整到 屏幕上,请使用 translationXtranslationY 属性。

下面是一个将视图移至位置 100 的 ObjectAnimator 示例 距离屏幕左边 2 秒的距离:

Kotlin

ObjectAnimator.ofFloat(view, "translationX", 100f).apply {
    duration = 2000
    start()
}

Java

ObjectAnimator animation = ObjectAnimator.ofFloat(view, "translationX", 100f);
animation.setDuration(2000);
animation.start();

此示例使用 ObjectAnimator.ofFloat() 方法,因为转换值必须为浮点数。第一个参数是 您想要添加动画效果的视图第二个参数是您要 动画效果由于视图需要水平移动,因此 translationX 属性。最后一个参数是动画的结束值。在本课中, 值 100 表示距离广告左侧许多像素的位置 屏幕上。

下一个方法会指定动画的时长(以毫秒为单位)。在本课中, 例如,动画运行 2 秒(2000 毫秒)。

最后一个方法会使动画运行,这会更新视图的位置 。

如需详细了解如何使用 ObjectAnimator,请参阅使用 ObjectAnimator

添加曲线动作

虽然使用 ObjectAnimator 很方便,但默认情况下它会重新放置 沿着起点和终点之间的直线显示视图。材质 设计采用曲线来呈现对象在屏幕上的空间移动, 动画的时间设置使用曲线运动,让应用给人一种更真实的感觉 同时制作更有趣的动画

定义您自己的路径

ObjectAnimator 类具有可用于为坐标添加动画效果的构造函数 同时使用两个或更多属性以及一条路径。对于 下面的 Animator 使用了一个 Path 对象,用于为 X 和 Y 添加动画效果 属性:

Kotlin

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    val path = Path().apply {
        arcTo(0f, 0f, 1000f, 1000f, 270f, -180f, true)
    }
    val animator = ObjectAnimator.ofFloat(view, View.X, View.Y, path).apply {
        duration = 2000
        start()
    }
} else {
    // Create animator without using curved path
}

Java

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
  Path path = new Path();
  path.arcTo(0f, 0f, 1000f, 1000f, 270f, -180f, true);
  ObjectAnimator animator = ObjectAnimator.ofFloat(view, View.X, View.Y, path);
  animator.setDuration(2000);
  animator.start();
} else {
  // Create animator without using curved path
}

以下是弧形动画的效果:

图 1. 曲线路径动画。

Interpolator 是缓和曲线的实现。请参阅 Material Design 文档 了解关于缓和曲线概念的更多信息。Interpolator 定义了如何根据 。系统会为 Material Design 规范:

  • @interpolator/fast_out_linear_in.xml
  • @interpolator/fast_out_slow_in.xml
  • @interpolator/linear_out_slow_in.xml

使用 PathInterpolator

通过 PathInterpolator 类是 Android 5.0 (API 21) 中引入的插值器。它基于 贝塞尔曲线Path 对象。Material Design 文档 加/减速 请使用 PathInterpolator

PathInterpolator 具有基于不同类型的贝塞尔曲线的构造函数。 所有贝塞尔曲线的起点和终点都固定为 (0,0)(1,1), 。其他构造函数参数取决于贝塞尔类型 曲线。

例如,对于二次贝塞尔曲线,只有 X 和 Y 坐标 一个控制点:

Kotlin

val myInterpolator = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    PathInterpolator(0.67f, 0.33f)
} else {
    LinearInterpolator()
}

Java

Interpolator myInterpolator = null;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
  myInterpolator = new PathInterpolator(0.67f, 0.33f);
} else {
  myInterpolator = new LinearInterpolator();
}

这样就产生了一条快速开始并随着速度减慢的缓和曲线 接近尾声。

三次贝塞尔构造函数同样具有固定的起点和终点, 需要两个控制点:

Kotlin

val myInterpolator = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    PathInterpolator(0.5f, 0.7f, 0.1f, 1.0f)
} else {
    LinearInterpolator()
}

Java

Interpolator myInterpolator = null;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
  myInterpolator = new PathInterpolator(0.5f, 0.7f, 0.1f, 1.0f);
} else {
  myInterpolator = new LinearInterpolator();
}

这是 Material Design 的实现,强调了 减速 加/减速曲线。

为了更好地进行控制,可以使用任意 Path 来定义曲线:

Kotlin

val myInterpolator = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
  val path = Path().apply {
    moveTo(0.0f, 0.0f)
    cubicTo(0.5f, 0.7f, 0.1f, 1.0f, 1.0f, 1.0f)
  }
  PathInterpolator(path)
} else {
  LinearInterpolator()
}

Java

Interpolator myInterpolator = null;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
  Path path = new Path();
  path.moveTo(0.0f, 0.0f);
  path.cubicTo(0.5f, 0.7f, 0.1f, 1.0f, 1.0f, 1.0f);
  myInterpolator = new PathInterpolator(path);
} else {
  myInterpolator = new LinearInterpolator();
}

这会生成与三次贝塞尔曲线示例相同的缓和曲线,但它使用 Path

您也可以将路径插值器定义为 XML 资源:

<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
    android:controlX1="0.5"
    android:controlY1="0.7"
    android:controlX2="0.1f"
    android:controlY2="1.0f"/>

创建 PathInterpolator 对象后,您可以将其传递给 Animator.setInterpolator() 方法。Animator 使用插值器确定时间或路径 开始运行

Kotlin

val animation = ObjectAnimator.ofFloat(view, "translationX", 100f).apply {
    interpolator = myInterpolator
    start()
}

Java

ObjectAnimator animation = ObjectAnimator.ofFloat(view, "translationX", 100f);
animation.setInterpolator(myInterpolator);
animation.start();