Untuk menyesuaikan cara animasi transisi elemen bersama berjalan, ada beberapa parameter yang dapat digunakan untuk mengubah cara transisi elemen bersama.
Spesifikasi animasi
Untuk mengubah spesifikasi animasi yang digunakan untuk gerakan ukuran dan posisi, Anda dapat
menentukan parameter boundsTransform
yang berbeda di Modifier.sharedElement()
.
Hal ini memberikan posisi Rect
awal dan posisi Rect
target.
Misalnya, untuk membuat teks dalam contoh sebelumnya bergerak dengan gerakan
busur, tentukan parameter boundsTransform
untuk menggunakan spesifikasi 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 ) )
Anda dapat menggunakan AnimationSpec
apa pun. Contoh ini menggunakan spesifikasi keyframes
.
boundsTransform
yang berbedaMode ubah ukuran
Saat menganimasikan antara dua batas bersama, Anda dapat menetapkan parameter resizeMode
ke RemeasureToBounds
atau ScaleToBounds
. Parameter ini menentukan cara
transisi elemen bersama di antara kedua status. ScaleToBounds
pertama kali
mengukur tata letak turunan dengan batasan lookahead (atau target). Kemudian, tata letak stabil turunan diskalakan agar sesuai dengan batas bersama.
ScaleToBounds
dapat dianggap sebagai "skala grafis" di antara status.
Sebaliknya, RemeasureToBounds
mengukur ulang dan menata ulang tata letak turunan
sharedBounds
dengan batasan tetap animasi berdasarkan ukuran target. Pengukuran ulang
dipicu oleh perubahan ukuran batas, yang berpotensi
menjadi setiap frame.
Untuk composable Text
, ScaleToBounds
direkomendasikan, karena menghindari penataan ulang
dan pengaliran ulang teks ke baris yang berbeda. RemeasureToBounds
direkomendasikan
untuk batas yang memiliki rasio aspek yang berbeda, dan jika Anda menginginkan kontinuitas yang lancar
antara dua elemen yang dibagikan.
Perbedaan antara kedua mode pengubahan ukuran dapat dilihat pada contoh berikut:
|
|
---|---|
Lewati ke tata letak akhir
Secara default, saat melakukan transisi antara dua tata letak, ukuran tata letak akan menganimasikan antara status awal dan akhir. Hal ini mungkin merupakan perilaku yang tidak diinginkan saat mengoanimasi konten seperti teks.
Contoh berikut mengilustrasikan teks deskripsi "Lorem Ipsum" yang masuk
ke layar dengan dua cara berbeda. Pada contoh pertama, teks akan di-reflow saat
masuk seiring bertambahnya ukuran penampung. Pada contoh kedua, teks tidak
di-flow ulang saat bertambah. Menambahkan Modifier.skipToLookaheadSize()
akan mencegah perataan ulang
seiring pertumbuhannya.
Tidak ada |
|
---|---|
Klip dan overlay
Agar elemen bersama dapat dibagikan di antara composable yang berbeda, rendering composable akan ditingkatkan menjadi overlay lapisan saat transisi dimulai ke pencocokannya di tujuan. Efeknya adalah transformasi ini akan keluar dari batas induk dan transformasi lapisannya (misalnya, alpha dan skala).
Elemen ini akan dirender di atas elemen UI non-bersama lainnya. Setelah transisi selesai, elemen akan dihapus dari overlay ke DrawScope
-nya sendiri.
Untuk memotong elemen bersama ke bentuk, gunakan fungsi Modifier.clip()
standar. Tempatkan setelah 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 )
Jika perlu memastikan bahwa elemen bersama tidak pernah dirender di luar penampung
induk, Anda dapat menetapkan clipInOverlayDuringTransition
di sharedElement()
. Secara
default, untuk batas bersama bertingkat, clipInOverlayDuringTransition
menggunakan jalur
klip dari sharedBounds()
induk.
Untuk mendukung agar elemen UI tertentu, seperti panel bawah atau tombol tindakan
mengambang, selalu berada di atas selama transisi elemen bersama, gunakan
Modifier.renderInSharedTransitionScopeOverlay()
. Secara default, pengubah
ini akan mempertahankan konten di overlay selama transisi
bersama aktif.
Misalnya, di Jetsnack, BottomAppBar
harus ditempatkan di atas
elemen bersama hingga layar tidak terlihat. Menambahkan pengubah
ke composable akan membuatnya tetap ditinggikan.
Tanpa |
Dengan |
---|---|
Anda mungkin ingin composable yang tidak dibagikan dianimasikan dan
tetap berada di atas composable lain sebelum transisi. Dalam kasus tersebut, gunakan
renderInSharedTransitionScopeOverlay().animateEnterExit()
untuk menganimasikan
composable saat transisi elemen bersama berjalan:
JetsnackBottomBar( modifier = Modifier .renderInSharedTransitionScopeOverlay( zIndexInOverlay = 1f, ) .animateEnterExit( enter = fadeIn() + slideInVertically { it }, exit = fadeOut() + slideOutVertically { it } ) )
Dalam kasus yang jarang terjadi, jika Anda ingin elemen bersama tidak dirender dalam
overlay, Anda dapat menetapkan renderInOverlayDuringTransition
di sharedElement()
ke salah (false).
Memberi tahu tata letak saudara tentang perubahan pada ukuran elemen bersama
Secara default, sharedBounds()
dan sharedElement()
tidak memberi tahu penampung induk
tentang perubahan ukuran apa pun saat tata letak bertransisi.
Untuk menyebarkan perubahan ukuran ke penampung induk saat bertransisi,
ubah parameter placeHolderSize
menjadi PlaceHolderSize.animatedSize
. Tindakan
tersebut akan menyebabkan item membesar atau mengecil. Semua item lain dalam tata letak merespons
perubahan.
|
(Perhatikan bagaimana item lain dalam daftar bergeser ke bawah sebagai respons terhadap satu item yang bertambah) |
---|---|