許多 Animation API 通常都接受參數來自訂動畫行為。
使用 AnimationSpec
參數自訂動畫
多數的動畫 API 都允許開發人員透過選用的 AnimationSpec
參數來自訂動畫規格。
val alpha: Float by animateFloatAsState( targetValue = if (enabled) 1f else 0.5f, // Configure the animation duration and easing. animationSpec = tween(durationMillis = 300, easing = FastOutSlowInEasing), label = "alpha" )
AnimationSpec
有多種類型,可用於建立不同類型的動畫。
使用 spring
製作物理動畫
spring
可在起始值和結束值之間建立以物理特性為基礎的動畫,並接受 2 個參數:dampingRatio
和 stiffness
。
dampingRatio
可定義彈簧的彈性,預設值為 Spring.DampingRatioNoBouncy
。
圖 1. 設定不同的彈簧阻尼比率。
stiffness
可定義彈簧朝結束值移動的速度,預設值為 Spring.StiffnessMedium
。
圖 2. 設定不同的彈簧剛度
val value by animateFloatAsState( targetValue = 1f, animationSpec = spring( dampingRatio = Spring.DampingRatioHighBouncy, stiffness = Spring.StiffnessMedium ), label = "spring spec" )
與以持續時間為基礎的 AnimationSpec
類型相比,spring
可在目標值於動畫期間發生變化時確保速率的持續性,因此能更順暢地處理中斷情形。許多動畫 API (例如 animate*AsState
和 updateTransition
) 會使用 spring
做為預設的 AnimationSpec。
舉例來說,如果我們將 spring
設定套用至由使用者觸控驅動的以下動畫,當動畫在進行時中斷,您會發現使用 tween
的回應速度不如使用 spring
來得流暢。
圖 3. 設定 tween
與 spring
的動畫規格,並造成乾擾。
使用緩和曲線和 tween
在起始值和結束值之間建立動畫
tween
會使用緩和曲線,透過指定的 durationMillis
於起始值和結束值之間建立動畫效果。tween
是「between」一詞的縮寫,表示兩個值之間的。
您也可以指定 delayMillis
來延遲動畫的開始時間。
val value by animateFloatAsState( targetValue = 1f, animationSpec = tween( durationMillis = 300, delayMillis = 50, easing = LinearOutSlowInEasing ), label = "tween delay" )
詳情請參閱「Easing」。
使用 keyframes
在特定時間以動畫呈現特定值
keyframes
會根據動畫期間不同時間戳記中指定的快照值建立動畫效果。在任何指定的時間,系統會在兩個主要畫面格值之間內插動畫值。針對對每個主要畫面格,都能指定 Easing 來決定內插曲線。
您可以選擇將在 0 毫秒和持續時間處指定值。如果不指定這些值,這些值會分別預設為動畫的起始值和結束值。
val value by animateFloatAsState( targetValue = 1f, animationSpec = keyframes { durationMillis = 375 0.0f at 0 using LinearOutSlowInEasing // for 0-15 ms 0.2f at 15 using FastOutLinearInEasing // for 15-75 ms 0.4f at 75 // ms 0.4f at 225 // ms }, label = "keyframe" )
使用 repeatable
重複動畫
repeatable
會重複執行以持續時間為基礎的動畫 (例如 tween
或 keyframes
),直到達到指定的疊代次數為止。您可以傳遞 repeatMode
參數以指定是否應該從開始 (RepeatMode.Restart
) 或結束 (RepeatMode.Reverse
) 開始重複播放動畫。
val value by animateFloatAsState( targetValue = 1f, animationSpec = repeatable( iterations = 3, animation = tween(durationMillis = 300), repeatMode = RepeatMode.Reverse ), label = "repeatable spec" )
使用 infiniteRepeatable
無限重複動畫
infiniteRepeatable
與 repeatable
類似,但會重複無限次的疊代。
val value by animateFloatAsState( targetValue = 1f, animationSpec = infiniteRepeatable( animation = tween(durationMillis = 300), repeatMode = RepeatMode.Reverse ), label = "infinite repeatable" )
在使用 ComposeTestRule
的測試中,系統不會執行使用 infiniteRepeatable
的動畫,而會使用每個動畫值的初始值來轉譯這個元件。
使用 snap
立即對齊結束值
snap
是一種特殊的 AnimationSpec
,可將值立即切換到結束值。您可以指定 delayMillis
以便延遲動畫的開始時間。
val value by animateFloatAsState( targetValue = 1f, animationSpec = snap(delayMillis = 50), label = "snap spec" )
設定自訂轉場函式
以持續時間為基礎的 AnimationSpec
作業 (例如 tween
或 keyframes
) 會使用 Easing
來調整動畫的分數。如此一來,動畫值就能加速或減速,而不是以固定速率移動。分數是介於 0 (起始) 和 1.0 (結束) 之間的值,表示動畫中的目前點。
Easing 實際上是一種函式,可接受介於 0 和 1.0 之間的分數值並傳回浮點值。傳回的值可能在範圍邊界外,代表過衝或是下衝。您可以建立自訂的 Easing,如以下程式碼所示。
val CustomEasing = Easing { fraction -> fraction * fraction } @Composable fun EasingUsage() { val value by animateFloatAsState( targetValue = 1f, animationSpec = tween( durationMillis = 300, easing = CustomEasing ), label = "custom easing" ) // …… }
Compose 提供多種內建 Easing
函式,可滿足大多數用途的需求。如要進一步瞭解如何根據您的情境使用哪些 Easing,請參閱「速度 - 質感設計」。
FastOutSlowInEasing
LinearOutSlowInEasing
FastOutLinearEasing
LinearEasing
CubicBezierEasing
- 顯示更多資訊
轉換至 AnimationVector
或從 AnimationVector
轉換自訂資料類型,來建立動畫
多數 Compose 動畫 API 預設支援 Float
、Color
、Dp
和其他基本資料類型做為動畫值,但有時您需要為其他資料類型 (包括自訂資料類型) 建立動畫。在動畫播放期間,任何動畫值都會以 AnimationVector
表示。使用對應的 TwoWayConverter
即可將值轉換為 AnimationVector
,反之亦然。這樣以來,核心動畫系統就能統一處理這些內容。舉例來說,Int
是以包含單一浮點值的 AnimationVector1D
代表。「Int
」的「TwoWayConverter
」看起來會像是這樣:
val IntToVector: TwoWayConverter<Int, AnimationVector1D> = TwoWayConverter({ AnimationVector1D(it.toFloat()) }, { it.value.toInt() })
基本上,Color
是紅色、綠色、藍色和 alpha 這 4 個值的組合,因此 Color
可轉換成包含 4 個浮點值的 AnimationVector4D
。透過這種方式,動畫中使用的每種資料類型都會轉換成 AnimationVector1D
、AnimationVector2D
、AnimationVector3D
或 AnimationVector4D
,視其維度而定。如此一來,您就能針對物件的不同元件個別建立動畫效果,而每個元件都有各自的速率追蹤。基本資料類型的內建轉換器可使用 Color.VectorConverter
或 Dp.VectorConverter
等轉換器存取。
如要想要為新的資料類型新增支援以作為動畫值,您可以建立專屬的 TwoWayConverter
並將其提供給 API。舉例來說,您可以使用 animateValueAsState
為自訂資料類型建立動畫效果,如下所示:
data class MySize(val width: Dp, val height: Dp) @Composable fun MyAnimation(targetSize: MySize) { val animSize: MySize by animateValueAsState( targetSize, TwoWayConverter( convertToVector = { size: MySize -> // Extract a float value from each of the `Dp` fields. AnimationVector2D(size.width.value, size.height.value) }, convertFromVector = { vector: AnimationVector2D -> MySize(vector.v1.dp, vector.v2.dp) } ), label = "size" ) }
下列清單包含一些內建 VectorConverter
:
Color.VectorConverter
Dp.VectorConverter
Offset.VectorConverter
Int.VectorConverter
Float.VectorConverter
IntSize.VectorConverter
為您推薦
- 注意:系統會在 JavaScript 關閉時顯示連結文字
- 以價值為準的動畫
- 疊代程式碼開發 {:#iterative-code-dev }
- Compose 中的動畫