如要自訂共用元素轉換動畫的執行方式,您可以使用幾個參數來變更共用元素轉換方式。
動畫規格
如要變更用於大小和位置移動的動畫規格,您可以在 Modifier.sharedElement()
上指定其他 boundsTransform
參數。這會提供初始 Rect
位置和目標 Rect
位置。
舉例來說,如要讓上述範例中的文字以弧形動作移動,請指定 boundsTransform
參數以使用 keyframes
規格:
val textBoundsTransform = BoundsTransform { initialBounds, targetBounds -> keyframes { durationMillis = boundsAnimationDurationMillis initialBounds at 0 using ArcMode.ArcBelow using FastOutSlowInEasing targetBounds at boundsAnimationDurationMillis } } Text( "Cupcake", fontSize = 28.sp, modifier = Modifier.sharedBounds( rememberSharedContentState(key = "title"), animatedVisibilityScope = animatedVisibilityScope, boundsTransform = textBoundsTransform ) )
您可以使用任何 AnimationSpec
。本範例使用 keyframes
規格。
boundsTransform
參數的範例調整大小模式
在兩個共用邊界之間建立動畫效果時,您可以設定 resizeMode
參數
改為 RemeasureToBounds
或 ScaleToBounds
這個參數可決定
在兩個狀態之間移動共用元素轉換。ScaleToBounds
會先使用預測 (或目標) 限制來評估子項版面配置。接著,
子項的穩定版面配置會經過縮放,以符合共用邊界。
ScaleToBounds
可視為「圖形比例」狀態之間
而 RemeasureToBounds
會重新測量及重新版面配置,
含有動畫固定限制的 sharedBounds
,根據目標大小設定。
重新評估作業是由邊界大小變更時觸發,這有可能
每幅畫面都不會改變
針對 Text
可組合項,建議使用 ScaleToBounds
,因為這可避免重新版面配置
以及文字重排進不同行針對不同層面的邊界
如果想讓兩個共用元素之間保持流暢性
建議時段為 RemeasureToBounds
。
以下範例說明兩種調整大小模式的差異:
|
|
---|---|
跳至最終版配置
根據預設,轉換兩個版面配置時,版面配置大小會呈現動畫效果 兩者之間的間隔在為文字等內容製作動畫時,這可能不是理想的行為。
以下範例說明「Lorem Ipsum」說明文字進入
以兩種不同的方式存取螢幕在第一個範例中,當容器大小增加時,文字會在進入時重新流動;在第二個範例中,文字不會在增加時重新流動。新增 Modifier.skipToLookaheadSize()
可防止自動重排
。
沒有 Modifier.skipToLookahead() - 請注意「Lorem Ipsum」文字重新流動 |
Modifier.skipToLookahead() - 請留意「Lorem Ipsum」文字保留在動畫開始播放時的最終狀態 |
---|---|
剪輯和重疊
在 Compose 中建立共用元素時,很重要的一點是依序 讓介面在不同的可組合項之間共用 轉換開始時,可組合項會提升為圖層疊加層 與目的地相符的檔案這會導致逃逸父項的邊界和其圖層轉換 (例如 alpha 和比例)。
在轉場效果後,這個物件會顯示在其他非共用的 UI 元素之上。
完成時,元素將會從疊加層中捨棄到它自己的 DrawScope
。
如要將共用元素裁剪成形狀,請使用標準 Modifier.clip()
函式。將其放在 sharedElement()
後方:
Image( painter = painterResource(id = R.drawable.cupcake), contentDescription = "Cupcake", modifier = Modifier .size(100.dp) .sharedElement( rememberSharedContentState(key = "image"), animatedVisibilityScope = this@AnimatedContent ) .clip(RoundedCornerShape(16.dp)), contentScale = ContentScale.Crop )
如果您需要確保共用元素絕不會在父項容器外顯示,可以為 sharedElement()
設定 clipInOverlayDuringTransition
。變更者:
預設值,如果是巢狀共用邊界,clipInOverlayDuringTransition
會使用裁剪
來自父項 sharedBounds()
的路徑。
如要支援在共用元素轉換期間,讓特定 UI 元素 (例如底部列或浮動動作按鈕) 一律位於頂端,請使用 Modifier.renderInSharedTransitionScopeOverlay()
。根據預設
修飾符會在分享期間,讓內容保留在疊加層中
以及轉換是否啟用
舉例來說,在 Jetsnack 中,BottomAppBar
必須放在共用元素的頂端,直到畫面無法顯示為止。新增修飾符
提升其品質
未提供 |
登入 |
---|---|
有時您可能會希望非共用可組合項在轉場前以動畫效果消失,並且停留在其他可組合項上方。在這種情況下,請使用
renderInSharedTransitionScopeOverlay().animateEnterExit()
即可製作動畫
可組合項退出:
JetsnackBottomBar( modifier = Modifier .renderInSharedTransitionScopeOverlay( zIndexInOverlay = 1f, ) .animateEnterExit( enter = fadeIn() + slideInVertically { it }, exit = fadeOut() + slideOutVertically { it } ) )
在極少數情況下,您希望共用元素不會在
重疊,您可以在 sharedElement()
上設定 renderInOverlayDuringTransition
設為 false
通知同層版面配置共用元素大小的變更
根據預設,sharedBounds()
和 sharedElement()
不會在版面配置轉換時通知父項容器任何大小變更。
如要在父項容器轉換期間套用大小變更
將 placeHolderSize
參數變更為 PlaceHolderSize.animatedSize
。執行
導致項目變大或縮小版面配置中的所有其他項目都會回應
相關變更
|
(請留意清單中其他項目如何因應持續增長的項目) |
---|---|