Animasyon değiştiricileri ve kompozit öğeleri

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

Kendisini gösteren ve gizleyen yeşil bir bileşimli öğe
Şekil 1. Bir sütundaki öğenin 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
    // ...
}

Varsayılan olarak içerik soluklaşıp genişler, kaybolarak kaybolur. 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. Böylece, AnimatedVisibility beste ağacına eklenir ekz animasyon tetiklemenize olanak sağlar. 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 bileşiğinde 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, animateEnterExit tarihine kadar çocukların her birinin ayrı animasyonlarına sahip olabilmesi için AnimatedVisibility öğesine 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 bu değeri anahtar olarak kullanır.

Varsayılan olarak ilk içerik yavaşça kaybolur ve daha sonra hedef içerik yavaşça kaybolur (bu davranışa fare arasından geçiş denir). transitionSpec parametresi için bir ContentTransform nesnesi belirterek bu animasyon davranışını özelleştirebilirsiniz. with infix işlevini kullanarak EnterTransition öğesini bir ExitTransition ile birleştirerek ContentTransform oluşturabilirsiniz. using iç dizili işleviyle 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()
        }
    }
}

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

AnimatedVisibility gibi, animateEnterExit değiştirici de AnimatedContent öğesinin içerik lambda'sında bulunur. 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, bir 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

Boyutunu sorunsuz bir şekilde değiştiren yeşil bir kompozisyon.
Şekil 2. Küçük ve büyük boyutlar arasında sorunsuz animasyonlar oluşturma

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.

Şu anda öneri yok.

Google Hesabınızda deneyin.