使用動畫移動檢視畫面

由於使用者在背景中進行互動或處理作業,經常需要重新調整畫面上的物件位置。比起立即更新物件的位置,導致物件從一個區域閃爍,而是改為使用動畫,從起始位置移至結束位置。

Android 可讓您使用 ObjectAnimator 重新調整畫面上檢視物件的位置。請提供您想要物件固定的結束位置,以及動畫的時間長度。您也可以使用時間內插器來控制動畫的加速或減速。

使用 ObjectAnimator 變更檢視畫面位置

ObjectAnimator API 可讓您以指定時間長度變更檢視畫面的屬性。其中包含的靜態方法,可根據您要建立動畫的屬性類型來建立 ObjectAnimator 執行個體。當您在畫面上重新調整檢視畫面的位置時,請使用 translationXtranslationY 屬性。

以下範例 ObjectAnimator 會在 2 秒內,將檢視畫面從螢幕左側移至 100 像素的位置:

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 類別包含多種建構函式,可讓您搭配路徑使用兩個以上的屬性,一次為座標建立動畫效果。舉例來說,下列動畫工具使用 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 規格的三個基本曲線提供 XML 資源:

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

使用 PathInterpoator

PathInterpolator 類別是 Android 5.0 (API 21) 中引入的內插器。它是以貝茲曲線Path 物件為基礎。加/減速的 Material Design 說明文件中的 Android 範例使用 PathInterpolator

PathInterpolator 具有以不同 Bézier 曲線類型為基礎的建構函式。所有 Bézier 曲線的開始與結束時間皆分別固定在 (0,0)(1,1) 中。其他建構函式引數取決於建立的 Bézier 曲線類型。

舉例來說,如果是二次圓弧形曲線,則只需要一個控制點的 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();
}

這會產生開始快速開始的加/減速曲線,並在接近結尾時減速。

Bézier 建構函式也同樣有固定的開始和結束時間點,但需要兩個控制點:

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

這是質感設計「強調減速」曲線的實作。

如要進一步控制,可以使用任意 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();
}

這會產生與 cubic Bézier 範例相同的加/減速曲線,但改用 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();