Compose, yaygın animasyon kullanım alanlarını işlemek için yerleşik birleştirilebilirler ve değiştiricilerle birlikte gelir.
Yerleşik animasyonlu bileşenler
AnimatedVisibility
ile öğelerin görünmesini ve kaybolmasını animasyonlu hale getirme
AnimatedVisibility
bileşeni, içeriğinin görünmesini ve kaybolmasını animasyonlu olarak gösterir.
var visible by remember { mutableStateOf(true) } // Animated visibility will eventually remove the item from the composition once the animation has finished. AnimatedVisibility(visible) { // your composable here // ... }
İçerik varsayılan olarak yavaşça belirip genişler ve yavaşça kaybolup küçülür. Geçiş, EnterTransition
ve ExitTransition
değerlerini belirterek özelleştirilebilir.
var visible by remember { mutableStateOf(true) } val density = LocalDensity.current AnimatedVisibility( visible = visible, enter = slideInVertically { // Slide in from 40 dp from the top. with(density) { -40.dp.roundToPx() } } + expandVertically( // Expand from the top. expandFrom = Alignment.Top ) + fadeIn( // Fade in with the initial alpha of 0.3f. initialAlpha = 0.3f ), exit = slideOutVertically() + shrinkVertically() + fadeOut() ) { Text( "Hello", Modifier .fillMaxWidth() .height(200.dp) ) }
Yukarıdaki örnekte görebileceğiniz gibi, birden fazla EnterTransition
veya ExitTransition
nesnesini bir +
operatörüyle birleştirebilirsiniz. Her nesne, davranışını özelleştirmek için isteğe bağlı parametreler kabul eder. Daha fazla bilgi için referanslara bakın.
EnterTransition
ve ExitTransition
örnekleri
AnimatedVisibility
, MutableTransitionState
alan bir varyant da sunar. Bu sayede, AnimatedVisibility
kompozisyon ağacına eklenir eklenmez bir animasyonu tetikleyebilirsiniz. Animasyon durumunu gözlemlemek için de kullanışlıdır.
// Create a MutableTransitionState<Boolean> for the AnimatedVisibility. val state = remember { MutableTransitionState(false).apply { // Start the animation immediately. targetState = true } } Column { AnimatedVisibility(visibleState = state) { Text(text = "Hello, world!") } // Use the MutableTransitionState to know the current animation state // of the AnimatedVisibility. Text( text = when { state.isIdle && state.currentState -> "Visible" !state.isIdle && state.currentState -> "Disappearing" state.isIdle && !state.currentState -> "Invisible" else -> "Appearing" } ) }
Çocuklar için giriş ve çıkış animasyonları
AnimatedVisibility
içindeki içerikler (doğrudan veya dolaylı alt öğeler), her biri için farklı animasyon davranışı belirtmek üzere animateEnterExit
değiştiricisini kullanabilir. Bu alt öğelerin her birinin görsel efekti, AnimatedVisibility
kompozitinde belirtilen animasyonlarla alt öğenin kendi giriş ve çıkış animasyonlarının bir birleşimidir.
var visible by remember { mutableStateOf(true) } AnimatedVisibility( visible = visible, enter = fadeIn(), exit = fadeOut() ) { // Fade in/out the background and the foreground. Box( Modifier .fillMaxSize() .background(Color.DarkGray) ) { Box( Modifier .align(Alignment.Center) .animateEnterExit( // Slide in/out the inner box. enter = slideInVertically(), exit = slideOutVertically() ) .sizeIn(minWidth = 256.dp, minHeight = 64.dp) .background(Color.Red) ) { // Content of the notification… } } }
Bazı durumlarda, çocukların animateEnterExit
ile kendi animasyonlarını kullanabilmesi için AnimatedVisibility
'nin hiç animasyon uygulamamasını isteyebilirsiniz. Bunu yapmak için AnimatedVisibility
bileşeninde EnterTransition.None
ve ExitTransition.None
değerlerini belirtin.
Özel animasyon ekleme
Yerleşik giriş ve çıkış animasyonları dışında özel animasyon efektleri eklemek istiyorsanız AnimatedVisibility
için içerik lambdası içindeki transition
özelliği aracılığıyla temel Transition
örneğine erişin. Geçiş örneğine eklenen tüm animasyon durumları, AnimatedVisibility
öğesinin giriş ve çıkış animasyonlarıyla aynı anda çalışır. AnimatedVisibility
, içeriğini kaldırmadan önce Transition
'taki tüm animasyonların tamamlanmasını bekler.
Transition
'ten bağımsız olarak oluşturulan çıkış animasyonları (animate*AsState
kullanımı gibi) AnimatedVisibility
tarafından hesaba katılamaz. Bu nedenle, derlenebilir içerikler bitmeden kaldırılabilir.
var visible by remember { mutableStateOf(true) } AnimatedVisibility( visible = visible, enter = fadeIn(), exit = fadeOut() ) { // this: AnimatedVisibilityScope // Use AnimatedVisibilityScope#transition to add a custom animation // to the AnimatedVisibility. val background by transition.animateColor(label = "color") { state -> if (state == EnterExitState.Visible) Color.Blue else Color.Gray } Box( modifier = Modifier .size(128.dp) .background(background) ) }
Transition
ile ilgili ayrıntılar için updateTransition işlevine bakın.
AnimatedContent
ile hedef duruma göre animasyon oluşturma
AnimatedContent
bileşeni, hedef duruma göre değişen içeriğini animasyonlu olarak gösterir.
Row { var count by remember { mutableIntStateOf(0) } Button(onClick = { count++ }) { Text("Add") } AnimatedContent( targetState = count, label = "animated content" ) { targetCount -> // Make sure to use `targetCount`, not `count`. Text(text = "Count: $targetCount") } }
lambda parametresini her zaman kullanmanız ve içeriğe yansıtmanız gerektiğini unutmayın. API, şu anda gösterilen içeriği tanımlamak için anahtar olarak bu değeri kullanır.
Varsayılan olarak, ilk içerik kaybolur ve ardından hedef içerik görünür hale gelir (bu davranışa kaybolma denir). transitionSpec
parametresine bir ContentTransform
nesnesi belirterek bu animasyon davranışını özelleştirebilirsiniz. with
iç birleşik işlevini kullanarak EnterTransition
ile ExitTransition
öğelerini birleştirerek ContentTransform
oluşturabilirsiniz. using
iç ayrımlı işlevini kullanarak SizeTransform
değerini ContentTransform
değerine uygulayabilirsiniz.
AnimatedContent( targetState = count, transitionSpec = { // Compare the incoming number with the previous number. if (targetState > initialState) { // If the target number is larger, it slides up and fades in // while the initial (smaller) number slides up and fades out. slideInVertically { height -> height } + fadeIn() togetherWith slideOutVertically { height -> -height } + fadeOut() } else { // If the target number is smaller, it slides down and fades in // while the initial number slides down and fades out. slideInVertically { height -> -height } + fadeIn() togetherWith slideOutVertically { height -> height } + fadeOut() }.using( // Disable clipping since the faded slide-in/out should // be displayed out of bounds. SizeTransform(clip = false) ) }, label = "animated content" ) { targetCount -> Text(text = "$targetCount") }
EnterTransition
, hedef içeriğin nasıl görüneceğini, ExitTransition
ise ilk içeriğin nasıl kaybolacağını tanımlar. AnimatedVisibility
için kullanılabilen tüm EnterTransition
ve ExitTransition
işlevlerine ek olarak AnimatedContent
, slideIntoContainer
ve slideOutOfContainer
işlevlerini de sunar.
Bunlar, slideInHorizontally/Vertically
ve slideOutHorizontally/Vertically
'e uygun alternatiflerdir. Bu işlevler, slayt mesafesini AnimatedContent
içeriğinin ilk içeriğin ve hedef içeriğin boyutlarına göre hesaplar.
SizeTransform
, boyutun başlangıç ve hedef içerikler arasında nasıl animasyonlu olarak değişeceğini tanımlar. Animasyonu oluştururken hem ilk boyuta hem de hedef boyuta erişebilirsiniz. SizeTransform
, animasyonlar sırasında içeriğin bileşen boyutuna kırpılıp kırpılmayacağını da kontrol eder.
var expanded by remember { mutableStateOf(false) } Surface( color = MaterialTheme.colorScheme.primary, onClick = { expanded = !expanded } ) { AnimatedContent( targetState = expanded, transitionSpec = { fadeIn(animationSpec = tween(150, 150)) togetherWith fadeOut(animationSpec = tween(150)) using SizeTransform { initialSize, targetSize -> if (targetState) { keyframes { // Expand horizontally first. IntSize(targetSize.width, initialSize.height) at 150 durationMillis = 300 } } else { keyframes { // Shrink vertically first. IntSize(initialSize.width, targetSize.height) at 150 durationMillis = 300 } } } }, label = "size transform" ) { targetExpanded -> if (targetExpanded) { Expanded() } else { ContentIcon() } } }
Çocuğun giriş ve çıkış geçişlerini animasyonlu hale getirme
AnimatedVisibility
gibi animateEnterExit
değiştirici de AnimatedContent
içeriği lambdası içinde kullanılabilir. Doğrudan veya dolaylı alt öğelerin her birine EnterAnimation
ve ExitAnimation
'yi ayrı ayrı uygulamak için bunu kullanın.
Özel animasyon ekleme
AnimatedVisibility
gibi transition
alanı da AnimatedContent
içeriği lambda'sında kullanılabilir. AnimatedContent
geçişiyle aynı anda çalışan özel bir animasyon efekti oluşturmak için bunu kullanın. Ayrıntılar için updateTransition işlevine bakın.
Crossfade
ile iki düzen arasında animasyonlu geçiş yapma
Crossfade
, iki düzen arasında geçişi yumuşak geçiş animasyonuyla yapar. current
parametresine iletilen değer değiştirilerek içerik, geçiş animasyonuyla değiştirilir.
var currentPage by remember { mutableStateOf("A") } Crossfade(targetState = currentPage, label = "cross fade") { screen -> when (screen) { "A" -> Text("Page A") "B" -> Text("Page B") } }
Yerleşik animasyon değiştiriciler
animateContentSize
ile birleştirilebilir boyut değişikliklerini canlandırma
animateContentSize
değiştirici, boyut değişikliğini animasyonlu olarak gösterir.
var expanded by remember { mutableStateOf(false) } Box( modifier = Modifier .background(colorBlue) .animateContentSize() .height(if (expanded) 400.dp else 200.dp) .fillMaxWidth() .clickable( interactionSource = remember { MutableInteractionSource() }, indication = null ) { expanded = !expanded } ) { }
Liste öğesi animasyonları
Eşsiz bir liste veya ızgaradaki öğelerin yeniden sıralamasını animasyonlu olarak göstermek istiyorsanız Eşsiz düzen öğe animasyonu dokümanlarına göz atın.
Sizin için önerilenler
- Not: JavaScript kapalıyken bağlantı metni gösterilir
- Değere dayalı animasyonlar
- Compose'daki animasyonlar
- Animasyon araçları desteği {:#tooling}