Để tuỳ chỉnh cách ảnh động chuyển đổi phần tử dùng chung chạy, bạn có thể sử dụng một số tham số để thay đổi cách chuyển đổi phần tử dùng chung.
Thông số kỹ thuật của ảnh động
Để thay đổi thông số kỹ thuật ảnh động dùng cho chuyển động kích thước và vị trí, bạn có thể chỉ định một tham số boundsTransform
khác trên Modifier.sharedElement()
.
Thao tác này cung cấp vị trí Rect
ban đầu và vị trí Rect
mục tiêu.
Ví dụ: để văn bản trong ví dụ trước di chuyển theo chuyển động hình vòng cung, hãy chỉ định tham số boundsTransform
để sử dụng thông số kỹ thuật 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 ) )
Bạn có thể sử dụng bất kỳ AnimationSpec
nào. Ví dụ này sử dụng thông số kỹ thuật keyframes
.
Chế độ đổi kích thước
Khi tạo ảnh động giữa hai giới hạn dùng chung, bạn có thể đặt tham số resizeMode
thành RemeasureToBounds
hoặc ScaleToBounds
. Tham số này xác định cách phần tử được chia sẻ chuyển đổi giữa hai trạng thái. Trước tiên, ScaleToBounds
đo lường bố cục con bằng các quy tắc ràng buộc trước (hoặc mục tiêu). Sau đó, bố cục ổn định của thành phần con được điều chỉnh theo tỷ lệ để vừa với các giới hạn dùng chung.
Bạn có thể coi ScaleToBounds
là "tỷ lệ đồ hoạ" giữa các trạng thái.
Trong khi đó, RemeasureToBounds
đo lường lại và bố trí lại bố cục con của sharedBounds
bằng các điều kiện ràng buộc cố định động dựa trên kích thước mục tiêu. Việc đo lường lại được kích hoạt bởi thay đổi về kích thước giới hạn, có thể là mọi khung hình.
Đối với các thành phần kết hợp Text
, bạn nên sử dụng ScaleToBounds
vì thành phần này sẽ tránh việc bố cục lại và luồng lại văn bản trên các dòng khác nhau. Đối với các giới hạn có tỷ lệ khung hình khác nhau và nếu bạn muốn có sự liên tục linh hoạt giữa hai phần tử được chia sẻ, bạn nên sử dụng RemeasureToBounds
.
Bạn có thể thấy sự khác biệt giữa hai chế độ đổi kích thước trong các ví dụ sau:
|
|
---|---|
Chuyển đến bố cục cuối cùng
Theo mặc định, khi chuyển đổi giữa hai bố cục, kích thước bố cục sẽ tạo ảnh động giữa trạng thái bắt đầu và trạng thái cuối cùng. Đây có thể là hành vi không mong muốn khi tạo ảnh động cho nội dung như văn bản.
Ví dụ sau đây minh hoạ văn bản mô tả "Lorem Ipsum" nhập vào màn hình theo hai cách khác nhau. Ví dụ đầu tiên, văn bản sẽ chảy lại khi đi vào khi kích thước vùng chứa tăng lên, ví dụ thứ hai, văn bản sẽ không chảy lại khi tăng kích thước. Việc thêm Modifier.skipToLookaheadSize()
sẽ ngăn quá trình chảy lại khi nó phát triển.
Không có Modifier.skipToLookahead() – hãy lưu ý văn bản "Lorem Ipsum" sẽ được kết xuất lại |
Modifier.skipToLookahead() – lưu ý văn bản "Lorem Ipsum" giữ nguyên trạng thái cuối cùng ở đầu ảnh động |
---|---|
Đoạn video và lớp phủ
Một khái niệm quan trọng khi tạo các phần tử dùng chung trong Compose là để các phần tử này có thể dùng chung giữa các thành phần kết hợp khác nhau, việc kết xuất thành phần kết hợp sẽ được nâng lên thành một lớp phủ khi quá trình chuyển đổi bắt đầu khớp với đích đến. Hiệu ứng của việc này là lớp con sẽ thoát khỏi giới hạn của lớp mẹ và các phép biến đổi lớp (ví dụ: alpha và tỷ lệ).
Lớp phủ này sẽ hiển thị trên các thành phần giao diện người dùng không dùng chung khác. Sau khi quá trình chuyển đổi hoàn tất, thành phần này sẽ được thả từ lớp phủ vào DrawScope
của chính nó.
Để cắt một phần tử dùng chung thành một hình dạng, hãy sử dụng hàm Modifier.clip()
tiêu chuẩn. Đặt sau 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 )
Nếu cần đảm bảo rằng một phần tử dùng chung không bao giờ hiển thị bên ngoài vùng chứa mẹ, bạn có thể đặt clipInOverlayDuringTransition
trên sharedElement()
. Theo mặc định, đối với các giới hạn dùng chung được lồng, clipInOverlayDuringTransition
sử dụng đường dẫn clip từ sharedBounds()
mẹ.
Để hỗ trợ việc giữ cho các thành phần trên giao diện người dùng cụ thể (chẳng hạn như thanh dưới cùng hoặc nút hành động nổi) luôn ở trên cùng trong quá trình chuyển đổi phần tử dùng chung, hãy sử dụng Modifier.renderInSharedTransitionScopeOverlay()
. Theo mặc định, đối tượng sửa đổi này sẽ giữ nội dung trong lớp phủ trong thời gian hiệu ứng chuyển đổi dùng chung đang hoạt động.
Ví dụ: trong Jetsnack, BottomAppBar
cần được đặt trên phần tử dùng chung cho đến khi màn hình không hiển thị. Việc thêm đối tượng sửa đổi vào thành phần kết hợp sẽ giúp thành phần kết hợp đó luôn ở trên.
Không có |
Với |
---|---|
Đôi khi, bạn có thể muốn thành phần kết hợp không được chia sẻ của mình tạo ảnh động cũng như vẫn nằm trên các thành phần kết hợp khác trước khi chuyển đổi. Trong những trường hợp như vậy, hãy sử dụng renderInSharedTransitionScopeOverlay().animateEnterExit()
để tạo ảnh động cho thành phần kết hợp khi quá trình chuyển đổi phần tử dùng chung chạy:
JetsnackBottomBar( modifier = Modifier .renderInSharedTransitionScopeOverlay( zIndexInOverlay = 1f, ) .animateEnterExit( enter = fadeIn() + slideInVertically { it }, exit = fadeOut() + slideOutVertically { it } ) )
Trong một số ít trường hợp, nếu muốn phần tử được chia sẻ không hiển thị trong lớp phủ, bạn có thể đặt renderInOverlayDuringTransition
trên sharedElement()
thành false.
Thông báo cho các bố cục đồng cấp về các thay đổi đối với kích thước phần tử dùng chung
Theo mặc định, sharedBounds()
và sharedElement()
không thông báo cho vùng chứa mẹ về mọi thay đổi về kích thước khi bố cục chuyển đổi.
Để truyền thay đổi về kích thước đến vùng chứa mẹ khi vùng chứa này chuyển đổi, hãy thay đổi tham số placeHolderSize
thành PlaceHolderSize.animatedSize
. Việc này sẽ làm cho mục đó tăng hoặc giảm. Tất cả các mục khác trong bố cục sẽ phản hồi thay đổi này.
|
(Lưu ý cách các mục khác trong danh sách di chuyển xuống để phản hồi việc một mục tăng lên) |
---|---|