animate*AsState
ile tek bir değeri canlandırın
animate*AsState
işlevleri, Compose'daki en basit animasyon API'leridir.
tek bir değer canlandırıyor. Yalnızca hedef değeri (veya bitiş değerini) sağlamanız ve
API, animasyonu geçerli değerden belirtilen değere başlatır.
Aşağıda, bu API'yi kullanarak alfa testi uygulama örneği verilmiştir. Yalnızca
animateFloatAsState
için hedef değere ayarlanmışsa alfa değeri artık bir animasyon değeridir
sağlanan değerler arasına (bu örnekte 1f
veya 0.5f
) girin.
var enabled by remember { mutableStateOf(true) } val alpha: Float by animateFloatAsState(if (enabled) 1f else 0.5f) Box( Modifier.fillMaxSize() .graphicsLayer(alpha = alpha) .background(Color.Red) )
Herhangi bir animasyon sınıfının veya işleyicinin örneğini oluşturmanız gerekmediğini unutmayın.
neden olabilir. Gelişmiş seçenekte, bir animasyon nesnesi (yani Animatable
örneği) çağrı sitesinde oluşturulur ve hatırlanır.
olduğunu varsayalım. Bundan sonra, bu composable'ı sağladığınızda
bir animasyon otomatik olarak başlatılır ve bu,
değer. Yayında zaten bir animasyon varsa animasyon kendi
geçerli değer (ve hız) gösterilir ve animasyon hedef değere doğru ilerler. Etkinlik sırasında
bu composable yeniden derlenir ve güncellenmiş bir animasyon döndürür
ne kadar değer verdiğinizi gösterir.
Compose, Float
için animate*AsState
işlevleri sunar.
Color
, Dp
, Size
, Offset
, Rect
, Int
, IntOffset
ve
IntSize
Bir
TwoWayConverter
- animateValueAsState
, genel bir tür alır.
Bir AnimationSpec
sağlayarak animasyon özelliklerini özelleştirebilirsiniz.
Daha fazla bilgi için AnimationSpec öğesine bakın.
Bir geçişle birden fazla mülkü aynı anda canlandırma
Transition
, bir veya daha fazla animasyonu alt öğeleri olarak yönetir ve çalıştırır
aynı anda birkaç farklı durumda.
Eyaletler herhangi bir veri türünde olabilir. Çoğu durumda özel bir enum
kullanabilirsiniz.
türünü ekleyin:
enum class BoxState { Collapsed, Expanded }
updateTransition
, Transition
örneği ile güncellemeleri oluşturup hatırlar
durumu.
var currentState by remember { mutableStateOf(BoxState.Collapsed) } val transition = updateTransition(currentState, label = "box state")
Ardından, bir alt öğe tanımlamak için animate*
uzantı işlevinden birini kullanabilirsiniz
animasyonu gösterilir. Eyaletlerin her biri için hedef değerleri belirtin.
Bu animate*
işlevleri, her karede güncellenen bir animasyon değeri döndürür.
güncellendiğinde animasyon sırasında
updateTransition
.
val rect by transition.animateRect(label = "rectangle") { state -> when (state) { BoxState.Collapsed -> Rect(0f, 0f, 100f, 100f) BoxState.Expanded -> Rect(100f, 100f, 300f, 300f) } } val borderWidth by transition.animateDp(label = "border width") { state -> when (state) { BoxState.Collapsed -> 1.dp BoxState.Expanded -> 0.dp } }
İsteğe bağlı olarak, farklı bir transitionSpec
parametresi belirtmek için
Geçiş durumu değişikliklerinin her bir kombinasyonu için AnimationSpec
. Görüntüleyin
AnimasyonSpec bölümüne göz atın.
val color by transition.animateColor( transitionSpec = { when { BoxState.Expanded isTransitioningTo BoxState.Collapsed -> spring(stiffness = 50f) else -> tween(durationMillis = 500) } }, label = "color" ) { state -> when (state) { BoxState.Collapsed -> MaterialTheme.colorScheme.primary BoxState.Expanded -> MaterialTheme.colorScheme.background } }
Bir geçiş hedef duruma ulaştığında, Transition.currentState
Transition.targetState
ile aynı olur. Bu, dönüşüm işlemi için
tamamlanıp tamamlanmadığını görebilirsiniz.
Bazen ilk hedeften farklı bir başlangıç durumu olmasını isteriz.
durumu. Şunları elde etmek için MutableTransitionState
ile updateTransition
kullanabiliriz:
bu. Örneğin, kod girer girmez animasyonu başlatmamıza olanak
bileşimi.
// Start in collapsed state and immediately animate to expanded var currentState = remember { MutableTransitionState(BoxState.Collapsed) } currentState.targetState = BoxState.Expanded val transition = updateTransition(currentState, label = "box state") // ……
Birden fazla composable işlev içeren daha karmaşık bir geçiş için
createChildTransition
kullanılır
alt geçiş oluşturun. Bu teknik, endişeleri
ayırmak için yararlıdır.
birden fazla alt bileşene
odaklanmasını sağlar. Üst geçiş işlemi,
alt geçişlerdeki tüm animasyon değerlerine dikkat edin.
enum class DialerState { DialerMinimized, NumberPad } @Composable fun DialerButton(isVisibleTransition: Transition<Boolean>) { // `isVisibleTransition` spares the need for the content to know // about other DialerStates. Instead, the content can focus on // animating the state change between visible and not visible. } @Composable fun NumberPad(isVisibleTransition: Transition<Boolean>) { // `isVisibleTransition` spares the need for the content to know // about other DialerStates. Instead, the content can focus on // animating the state change between visible and not visible. } @Composable fun Dialer(dialerState: DialerState) { val transition = updateTransition(dialerState, label = "dialer state") Box { // Creates separate child transitions of Boolean type for NumberPad // and DialerButton for any content animation between visible and // not visible NumberPad( transition.createChildTransition { it == DialerState.NumberPad } ) DialerButton( transition.createChildTransition { it == DialerState.DialerMinimized } ) } }
AnimatedVisibility
ve AnimatedContent
ile geçişi kullanın
AnimatedVisibility
ve AnimatedContent
Transition
öğesinin uzantı işlevleri olarak kullanılabilir. Şu tarih için targetState
:
Transition.AnimatedVisibility
ve Transition.AnimatedContent
türetildi
ve giriş/çıkış geçişlerini gerektiği gibi tetiklemek içinTransition
Transition
adlı çocuğun targetState
ayarı değişti. Bu uzantı işlevleri
için dahili olacak olan Enter/exit/sizeTransform animasyonları
AnimatedVisibility
/AnimatedContent
, Transition
içine kaldırılacak.
Bu uzantı işlevleriyle, AnimatedVisibility
/AnimatedContent
öğesinin durumu
gözlemlenebilirsiniz. Boole visible
parametresi yerine,
AnimatedVisibility
uygulamasının bu sürümü, üst öğeyi dönüştüren bir lambda alıyor
geçişin hedef durumunu boole'ye dönüştürür.
Ayrıntılar için Animated visibility ve AnimatedContent'e göz atın.
var selected by remember { mutableStateOf(false) } // Animates changes when `selected` is changed. val transition = updateTransition(selected, label = "selected state") val borderColor by transition.animateColor(label = "border color") { isSelected -> if (isSelected) Color.Magenta else Color.White } val elevation by transition.animateDp(label = "elevation") { isSelected -> if (isSelected) 10.dp else 2.dp } Surface( onClick = { selected = !selected }, shape = RoundedCornerShape(8.dp), border = BorderStroke(2.dp, borderColor), elevation = elevation ) { Column(modifier = Modifier.fillMaxWidth().padding(16.dp)) { Text(text = "Hello, world!") // AnimatedVisibility as a part of the transition. transition.AnimatedVisibility( visible = { targetSelected -> targetSelected }, enter = expandVertically(), exit = shrinkVertically() ) { Text(text = "It is fine today.") } // AnimatedContent as a part of the transition. transition.AnimatedContent { targetState -> if (targetState) { Text(text = "Selected") } else { Icon(imageVector = Icons.Default.Phone, contentDescription = "Phone") } } } }
Bir geçişi kapsama ve yeniden kullanılabilir hale getirme
Basit kullanım alanları için, geçiş animasyonlarını son derece geçerli bir seçenek. Karmaşık bir bileşen üzerinde çalışırken ancak animasyonlu değerleri birbirinden ayırmak isteyebilirsiniz. composable kullanıcı arayüzünden uygulanmasını sağlar.
Bunu, tüm animasyon değerlerini içeren bir sınıf ve söz konusu sınıfın bir örneğini döndüren "update" işlevi. Geçiş çıkarımı da yeni ayrı işleve çıkarılabilir. Bu kalıp animasyon mantığını merkezileştirme veya karmaşık hale getirme konusunda kullanışlıdır. animasyonları yeniden kullanabilirsiniz.
enum class BoxState { Collapsed, Expanded } @Composable fun AnimatingBox(boxState: BoxState) { val transitionData = updateTransitionData(boxState) // UI tree Box( modifier = Modifier .background(transitionData.color) .size(transitionData.size) ) } // Holds the animation values. private class TransitionData( color: State<Color>, size: State<Dp> ) { val color by color val size by size } // Create a Transition and return its animation values. @Composable private fun updateTransitionData(boxState: BoxState): TransitionData { val transition = updateTransition(boxState, label = "box state") val color = transition.animateColor(label = "color") { state -> when (state) { BoxState.Collapsed -> Color.Gray BoxState.Expanded -> Color.Red } } val size = transition.animateDp(label = "size") { state -> when (state) { BoxState.Collapsed -> 64.dp BoxState.Expanded -> 128.dp } } return remember(transition) { TransitionData(color, size) } }
rememberInfiniteTransition
ile sonsuz sayıda tekrar eden bir animasyon oluşturun
InfiniteTransition
, Transition
gibi bir veya daha fazla alt animasyon içerir, ancak
besteye girdikleri anda animasyonlar çalışmaya başlar ve
devam eder. InfiniteTransition
örneği oluşturabilirsiniz
rememberInfiniteTransition
ile. Alt animasyonlar
animateColor
, animatedFloat
veya animatedValue
. Ayrıca,
Animasyonu belirtmek için infinite Repeatable
özellikler.
val infiniteTransition = rememberInfiniteTransition() val color by infiniteTransition.animateColor( initialValue = Color.Red, targetValue = Color.Green, animationSpec = infiniteRepeatable( animation = tween(1000, easing = LinearEasing), repeatMode = RepeatMode.Reverse ) ) Box(Modifier.fillMaxSize().background(color))
Alt düzey animasyon API'leri
Önceki bölümde bahsedilen tüm üst düzey animasyon API'leri en iyi uygulamaları paylaşacağım.
animate*AsState
işlevleri, anında görsel oluşturan en basit API'lerdir
değerinin animasyon değeri olarak değişmesi. Desteklenen bir kaynak olan Animatable
,
eş yordam tabanlı API'dir. updateTransition
,
birden fazla animasyon değerini yönetebilen ve bunları temel alarak çalıştırabilen geçiş nesnesi
tercih edebilirsiniz. rememberInfiniteTransition
benzer ancak
çalışmaya devam eden birden çok animasyonu yönetebilen sonsuz geçiş
koruyabilmelidir. Animatable
hariç tüm bu API'ler composable'dır.
bu animasyonların bestenin dışında oluşturulabileceği anlamına gelir.
Bu API'lerin tümü daha temel Animation
API'ye dayanır. En fazla
Uygulamalar doğrudan Animation
ile etkileşime geçmeyecek. Özelleştirmenin bir kısmı
Animation
özellikleri üst düzey API'ler aracılığıyla kullanılabilir. Görüntüleyin
Aşağıdakiler hakkında daha fazla bilgi için animasyonları özelleştirme
AnimationVector
ve AnimationSpec
.
Animatable
: Koordine tabanlı tek değerli animasyon
Animatable
, değeri değiştirildiğinde değeri animasyon oluşturabilen bir değer sahibidir.
animateTo
. Bu, animate*AsState
uygulamasını yedekleyen API'dir.
Tutarlı bir devamlılık ve karşılıklı dışlama sağlar. Diğer bir deyişle,
değer değişikliği her zaman devam eder ve devam eden animasyonlar iptal edilir.
Animatable
ürününün animateTo
dahil birçok özelliği askıya alma olarak sunuluyor
işlevlerine dahildir. Bu, öğelerin uygun bir eş yordam içine alınması gerektiği anlamına gelir
kapsam. Örneğin, LaunchedEffect
composable'ı kullanarak
kapsamı yalnızca belirtilen anahtar değeri süresince uygular.
// Start out gray and animate to green/red based on `ok` val color = remember { Animatable(Color.Gray) } LaunchedEffect(ok) { color.animateTo(if (ok) Color.Green else Color.Red) } Box(Modifier.fillMaxSize().background(color.value))
Yukarıdaki örnekte, Animatable
örneği oluşturup hatırlayacağız.
Color.Gray
başlangıç değeri. Boole işaretinin değerine bağlı olarak
ok
, renk canlandırmasını Color.Green
veya Color.Red
olarak gösterir. Sonraki herhangi bir
boole değerine geçiş yapıldığında animasyon diğer renge başlar. Bir
animasyon iptal edildiğinde ve
yeni animasyon, geçerli hızla geçerli anlık görüntü değerinden başlar.
Bu, animate*AsState
API'yi yedekleyen animasyon uygulamasıdır
ele alacağız. animate*AsState
ile karşılaştırıldığında,
Animatable
doğrudan bize çeşitli konularda daha ayrıntılı kontrol sağlar. İlk olarak,
Animatable
, ilk hedef değerinden farklı bir başlangıç değerine sahip olabilir.
Örneğin, yukarıdaki kod örneğinde ilk başta gri bir kutu gösterilmektedir.
yeşile veya kırmızıya dönüşmeye başlar. İkinci olarak, Animatable
snapTo
ve animateDecay
olmak üzere içerik değerine ilişkin işlemlerdir. snapTo
.
geçerli değeri hemen hedef değere ayarlar. Bu,
tek doğru kaynağı değildir ve diğer reklam biçimleriyle
(ör. dokunma etkinlikleri) animateDecay
, yavaşlayan bir animasyon başlatır
kaldırmamız gerekir. Bu, hızla kaydırma davranışını uygulamak için yararlıdır. Görüntüleyin
Daha fazla bilgi için hareket ve animasyon.
Animatable
, Float
ve Color
özelliklerini hemen destekler ancak tüm veri türleri aşağıdaki gibi olabilir:
bir TwoWayConverter
sağlanarak kullanılabilir. Görüntüleyin
AnimasyonVector sayfasına göz atın.
AnimationSpec
sağlayarak animasyon özelliklerini özelleştirebilirsiniz.
Daha fazla bilgi için AnimationSpec öğesine bakın.
Animation
: Manuel olarak kontrol edilen animasyon
Animation
, kullanılabilen en düşük düzey Animasyon API'sidir. Animasyonların çoğu
temel aldığı bir etkinlik
geliştirdik. İki Animation
alt türü vardır:
TargetBasedAnimation
ve DecayAnimation
.
Animation
, yalnızca animasyonun zamanını manuel olarak kontrol etmek için kullanılmalıdır.
Animation
, durum bilgisizdir ve herhangi bir yaşam döngüsü kavramı yoktur. Google
üst düzey API'lerin kullandığı bir animasyon hesaplama motoru görevi görür.
TargetBasedAnimation
Diğer API'ler çoğu kullanım alanını kapsar ancak doğrudan TargetBasedAnimation
kullanılır
animasyon oynatma süresini kendiniz kontrol etmenizi sağlar. Aşağıdaki örnekte,
TargetAnimation
cihazının oynatma süresi, kareye göre manuel olarak kontrol edilir.
saat withFrameNanos
tarafından sağlanmıştır.
val anim = remember { TargetBasedAnimation( animationSpec = tween(200), typeConverter = Float.VectorConverter, initialValue = 200f, targetValue = 1000f ) } var playTime by remember { mutableStateOf(0L) } LaunchedEffect(anim) { val startTime = withFrameNanos { it } do { playTime = withFrameNanos { it } - startTime val animationValue = anim.getValueFromNanos(playTime) } while (someCustomCondition()) }
DecayAnimation
TargetBasedAnimation
özelliğinden farklı olarak,
DecayAnimation
bir targetValue
sağlanmasını gerektirmez. Bunun yerine,
Başlangıç koşullarına göre targetValue
, initialVelocity
ve
initialValue
ve sağlanan DecayAnimationSpec
.
Azaltma animasyonları, genellikle bir sallama hareketinden sonra öğeleri yavaşlatmak için kullanılır.
dur. Animasyon hızı, initialVelocityVector
tarafından ayarlanan değerde başlar
zamanla yavaşlar.
Sizin için önerilenler
- Not: JavaScript kapalıyken bağlantı metni gösterilir
- Animasyonları özelleştirme {:#customize-animations}
- Compose'da animasyonlar
- Animasyon değiştiricileri ve composable'lar