Jetpack Compose Animation: Transition ve AnimatedVisibility Pratik Uygulamalar
Jetpack Compose'da animasyon yapmak eski Android'den çok daha basit. AnimatedVisibility ve Transition, UI elemanlarını pürüzsüz bir şekilde gösterip gizlemenin temel araçları. Fakat birçok geliştirici bu iki API'yi karıştırıyor veya yanlış durumda kullanıyor.
AnimatedVisibility, bir composable'ı belirli bir koşula göre göstermek veya gizlemek için kullanılır. Görünür hale geldiğinde giriş animasyonu, gizlenirken çıkış animasyonu oynatılır.
Temel yapı şöyle:
1AnimatedVisibility(2visible = isVisible,3enter = fadeIn() + expandVertically(),4exit = fadeOut() + shrinkVertically()5) {6Text("Merhaba!")7}Burada neler oluyor? visible parametresi true olunca metin görünür ve enter animasyonu oynatılır. False olunca exit animasyonu oynatıldıktan sonra metin tamamen gizlenir. fadeIn() şeffaflık değişimi, expandVertically() ise yükseklik değişimi yapar. Bunları + operatörüyle birleştiriyorsun, böylece ikisi aynı anda oynatılıyor.
Transition, bir durumdan diğerine geçişi yönetir. AnimatedVisibility gibi sadece görünürlük değil, birçok özelliği aynı anda animasyonla değiştirebilirsin.
1val state = remember { mutableStateOf(false) }2val transition = updateTransition(targetState = state.value)34val backgroundColor by transition.animateColor(5label = "bg color"6) { isExpanded ->7if (isExpanded) Color.Green else Color.Red8}910val size by transition.animateDp(11label = "size"12) { isExpanded ->13if (isExpanded) 200.dp else 100.dp14}1516Box(17modifier = Modifier.size(size).background(backgroundColor).clickable { state.value =!state.value }18)Transition, state değiştiğinde tüm animasyonları eşzamanlı olarak başlatır. Renk ve boyut aynı anda değişir. Neden Transition'ı AnimatedVisibility yerine kullanıyoruz? Çünkü burada sadece görünürlük değil, birden fazla özellik değişiyor ve hepsi senkronize olması gerekiyor.
Kullanıcı butona tıkladığında genişleyen, rengi değişen ve içerisinde metin gösteren bir bileşen yapalım:
1@Composable2fun ExpandableButton() {3val isExpanded = remember { mutableStateOf(false) }4val transition = updateTransition(targetState = isExpanded.value)56val width by transition.animateDp(label = "width") {7if (it) 300.dp else 100.dp8}910val backgroundColor by transition.animateColor(label = "bg") {11if (it) Color.Blue else Color.Gray12}1314Button(15onClick = { isExpanded.value =!isExpanded.value },16modifier = Modifier.width(width).height(50.dp),17colors = ButtonDefaults.buttonColors(containerColor = backgroundColor)18) {19AnimatedVisibility(20visible = isExpanded.value,21enter = fadeIn(),22exit = fadeOut()23) {24Text("Genişledim!")25}26if (!isExpanded.value) {27Text("Tıkla")28}29}30}Bu örnekte Transition butonun genişliği ve rengiyle ilgileniyor. AnimatedVisibility ise metni gösterip gizliyor. İkisi birlikte çalışıyor.
Hata 1: AnimatedVisibility içinde state değişikliği yapmak. AnimatedVisibility'nin içinde visible parametresini değiştiren bir buton koyarsan, animasyon yarıda kesilir. Durumu dışarıda yönet.
Hata 2: Transition'da çok fazla animasyon. 5-6 özelliği aynı anda animasyonla değiştirirsen UI donabilir. Önemli olanları seç.
Hata 3: Animasyon süresi ayarlamamak. Varsayılan 300ms hızlı gelebilir. animationSpec = tween(durationMillis = 800) ekle.
1val size by transition.animateDp(2transitionSpec = {3tween(durationMillis = 500, easing = EaseInOutCubic)4},5label = "size"6) { isExpanded ->7if (isExpanded) 200.dp else 100.dp8}Animasyonun akışını kontrol etmek için easing fonksiyonları kullan. EaseInOutCubic başlangıçta yavaş, ortada hızlı, sonda yavaş hareket eder. Daha doğal görünüyor.
9 yorum
transition birden fazla şeyi aynı anda animate etmen gerektiğinde işe yaradığını düşün mesela renk değişirken boyut da değişiyorsa ikisini synchronized tutmak gerekir animatedvisibilityde bu kadar kontrol yok
aynen işte öyle animatedvisibility senin yerine durumu kontrol ediyor transitionda sen her şeyi elle yönetmek zorundasın
yani transition kullanırken ben kendim remember ile state tutmak zorunda kalıyorum animatedvisibility ise visible parametresini geçince otomatik halletmiş oluyor öyle mi
ama transition da visible parametresi var yani o da göster/gizle yapabiliyor mu
anladım şimdi yani transition seçtiğim multiple propertyler için synchronized animation yapabiliyorum ama animatedvisibility sadece enter/exit için optimize edilmiş gibi
o zaman transition ne zaman kullanalım ki animatedvisibility her şeyi yapıyorsa
evet transition de yapabiliyor ama animatedvisibility daha kolay transitionda sen state yönetmek zorundasın
transition daha çok renk değişikliği boyut değişimi gibi şeylerde işe yaradığını düşün
AnimatedVisibilitynin visible parametresi false olunca animasyon oynatılıyor da transition ne zaman işe yaradığını tam anlamadım ikisi aynı şey gibi geldi bana