Animasyon değiştiricileri ve kompozit öğeleri

Compose, animasyonların yaygın kullanım alanlarını yönetmek için yerleşik composable'lar ve değiştiriciler içerir.

Yerleşik animasyonlu composable'lar

AnimatedVisibility ile görünüşü ve kaybolma anını canlandırın

Kendisini gizleyen yeşil composable
Şekil 1. Bir sütundaki bir öğenin görünümünü ve kaybolmasını canlandırma
'nı inceleyin.

İlgili içeriği oluşturmak için kullanılan AnimatedVisibility composable, içeriğinin görünümüne ve ortadan kalkmasına animasyon ekler.

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 soluklaşıp genişler ve yavaş yavaş kararma ve küçülme yaşar. Geçiş, EnterTransition ve ExitTransition.

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 öğesini birleştirebilirsiniz. veya + operatörü içeren ExitTransition nesne ve bunların her biri isteğe bağlı kabul eder parametrelerini kullanır. Daha fazla bilgi için referanslara göz atın.

EnterTransition ve ExitTransition örnekleri

GirişGeçişi ÇıkışGeçişi
fadeIn
kararma animasyonu
fadeOut
kararma animasyonu
slideIn
kaydırma animasyonu
slideOut
dışa kaydırma animasyonu
slideInHorizontally
yatay kaydırma animasyonu
slideOutHorizontally
yatay olarak dışarı kaydırma animasyonu
slideInVertically
dikey kaydırma animasyonu
slideOutVertically
dikey kaydırma animasyonu
scaleIn
animasyonda ölçekleme
scaleOut
ölçeği genişletme animasyonu
expandIn
animasyonda genişlet
shrinkOut
animasyonu küçült
expandHorizontally
yatay olarak genişletme animasyonu
shrinkHorizontally
yatay küçültme animasyonu
expandVertically
dikey genişletme animasyonu
shrinkVertically
dikey küçültme animasyonu

AnimatedVisibility da bir varyant sunuyor: MutableTransitionState. Bu, bir animasyonu etkinleştiği anda tetiklemenize AnimatedVisibility, beste ağacına eklendi. Ayrıca proje yöneticisi olarak animasyon durumunu gözlemleyeceğiz.

// 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ış animasyonu

AnimatedVisibility kapsamındaki içerik (doğrudan veya dolaylı çocuklar), animateEnterExit değiştiricisi kullanabilirsiniz. Görsel etkisi, her bir alt öğe için belirtilen animasyonların AnimatedVisibility composable'da, çocuğun kendi girişinde ve çıkış animasyonları.

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, AnimatedVisibility öğesinin animasyon uygulamamasını isteyebilirsiniz. Böylece çocukların her biri kendine özgü animasyonlara sahip olabilir. animateEnterExit. Bunu yapmak için EnterTransition.None ve AnimatedVisibility composable'da ExitTransition.None.

Özel animasyon ekle

Yerleşik giriş ve çıkışın ötesinde özel animasyon efektleri eklemek istiyorsanız animasyonları eklemek için transition üzerinden temel Transition örneğine erişin mülkü olan içerik lambda'sında AnimatedVisibility için belirtilen değer. Herhangi bir animasyon Geçiş örneğine eklenen durumlar, Enter tuşu ile eş zamanlı olarak çalışır ve AnimatedVisibility animasyonlarının çıkış animasyonlarını içerir. AnimatedVisibility şu saate kadar bekliyor: içeriği kaldırılmadan önce Transition içindeki tüm animasyonlar tamamlandı. Transition öğesinden bağımsız olarak oluşturulan çıkış animasyonları (örneğin, animate*AsState) içeriyorsa AnimatedVisibility bunları hesaba katamaz. Bu nedenle, composable'ın içeriği tamamlanmadan kaldırabilir.

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 sayfasına bakın.

AnimatedContent ile hedef duruma göre animasyon uygula

AnimatedContent composable, hedef durumu.

Row {
    var count by remember { mutableStateOf(0) }
    Button(onClick = { count++ }) {
        Text("Add")
    }
    AnimatedContent(targetState = count) { targetCount ->
        // Make sure to use `targetCount`, not `count`.
        Text(text = "Count: $targetCount")
    }
}

Her zaman lambda parametresini kullanmanız ve bunu içerik. API, tarafından yayınlanan içeriği tanımlamak için bu değeri anahtar olarak kullanır. şu anda gösteriliyor.

Varsayılan olarak başlangıçtaki içerik yavaşça kaybolur ve hedef içerik (bu davranışa şeffaflaşma adı verilir). Siz ContentTransform transitionSpec parametresi. ContentTransform oluşturmak için EnterTransition ExitTransition ile (with tekerlek) işlevini kullanın. SizeTransform değerini uygulayabilirsiniz ContentTransform öğesine ekleyerek using iç ek işlevi.

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() with
                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() with
                slideOutVertically { height -> height } + fadeOut()
        }.using(
            // Disable clipping since the faded slide-in/out should
            // be displayed out of bounds.
            SizeTransform(clip = false)
        )
    }
) { targetCount ->
    Text(text = "$targetCount")
}

EnterTransition, hedef içeriğin nasıl görünmesi gerektiğini tanımlar. ExitTransition, ilk içeriğin nasıl kaybolması gerektiğini tanımlar. Ayrıca tüm EnterTransition ve ExitTransition işlevlerinin AnimatedVisibility, AnimatedContent slideIntoContainer sunuyor ve slideOutOfContainer. Bunlar, slideInHorizontally/Vertically ve Slayt mesafesini şuna göre hesaplayan slideOutHorizontally/Vertically: ilk içeriğin boyutlarının ve videonun hedef içeriğinin AnimatedContent içerik.

SizeTransform, boyutu başlangıçtaki ve hedef içerikler arasında hareketli olmalıdır. Bakiyeniz hem başlangıç boyutuna hem de hedef boyuta erişebilirsiniz. animasyon ekler. SizeTransform, içeriğin kırpılıp kırpılmayacağını da kontrol eder yeni bir boyut oluşturabilirsiniz.

var expanded by remember { mutableStateOf(false) }
Surface(
    color = MaterialTheme.colorScheme.primary,
    onClick = { expanded = !expanded }
) {
    AnimatedContent(
        targetState = expanded,
        transitionSpec = {
            fadeIn(animationSpec = tween(150, 150)) with
                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
                        }
                    }
                }
        }
    ) { targetExpanded ->
        if (targetExpanded) {
            Expanded()
        } else {
            ContentIcon()
        }
    }
}

Alt giriş ve çıkış geçişlerini canlandırma

AnimatedVisibility gibi, animateEnterExit değiştiricisi, AnimatedContent öğesinin içerik lambda'sında bulunmaktadır. Bunu kullan EnterAnimation ve ExitAnimation özelliklerini doğrudan veya dolaylı ayrı olarak ele alacağız.

Özel animasyon ekle

AnimatedVisibility gibi, transition alanı da AnimatedContent içerik lambda'sı. Özel bir animasyon oluşturmak için bunu kullanın AnimatedContent geçişiyle eş zamanlı olarak çalışan efekt. Görüntüleyin updateTransition hakkında daha fazla bilgi edinin.

Crossfade ile iki düzen arasında animasyon oluşturun

Crossfade, iki düzen arasında çapraz geçiş animasyonuyla canlanıyor. Geçiş yaparak current parametresine geçirilen değer değiştirildiğinde, içerik geçiş animasyonu.

var currentPage by remember { mutableStateOf("A") }
Crossfade(targetState = currentPage) { screen ->
    when (screen) {
        "A" -> Text("Page A")
        "B" -> Text("Page B")
    }
}

Yerleşik animasyon değiştiricileri

animateContentSize ile composable boyut değişikliklerini canlandırın

Yeşil composable, boyut değişimine sorunsuz şekilde dokunuyor.
Şekil 2. Küçük ve büyük boyutlar arasında sorunsuz animasyonlar oluşturma
'nı inceleyin.

animateContentSize değiştiricisi, boyut değişikliğini canlandırır.

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ı

Tembel liste veya ızgaradaki öğe yeniden sıralamalarına animasyon eklemek istiyorsanız Geç düzen öğesi animasyonu dokümanları.

ziyaret edin.