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