使用動畫移動檢視畫面

試試 Compose 的方式
Jetpack Compose 是 Android 推薦的 UI 工具包。瞭解如何在 Compose 中使用動畫。

由於使用者互動或幕後處理,螢幕上的物件經常需要重新定位。請勿立即更新物件的位置,否則會導致物件從一個區域閃爍到另一個區域,請改用動畫將物件從起始位置移至結束位置。

Android 允許您在螢幕上重新調整檢視物件的位置,是使用 ObjectAnimator。您可以提供物件要停留的終點位置,以及動畫的時間長度。您也可以使用時間插補器控制動畫的加速或減速。

使用 ObjectAnimator 變更檢視畫面位置

ObjectAnimator API 提供一種方法,可變更指定時間長度的檢視畫面屬性。它包含靜態方法,可根據您要製作動畫的屬性類型建立 ObjectAnimator 例項。調整檢視畫面在螢幕上的位置時,請使用 translationXtranslationY 屬性。

以下是 ObjectAnimator 的範例,這個 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 很方便,但預設會沿著起點和終點之間的直線重新定位檢視畫面。Material Design 的設計仰賴曲線在螢幕上的物件空間移動,以及動畫的時間。使用彎曲動作可讓應用程式更具 Material Design 風格,同時讓動畫更生動有趣。

自行定義路徑

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

使用 PathInterpolator

PathInterpolator 類別是 Android 5.0 (API 21) 推出的插補器。它是以 Bézier 曲線Path 物件為基礎。Material Design 說明文件中的 Android 範例使用 PathInterpolator

PathInterpolator 具有以不同類型貝茲曲線為基礎的建構函式。所有貝茲曲線的起點和終點分別固定為 (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();
}

這是 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();