Animasyonları özelleştir

Animasyon API'lerinin çoğu, davranışını özelleştirmek için genellikle parametreleri kabul eder.

Animasyonları AnimationSpec parametresiyle özelleştirme

Animasyon API'lerinin çoğu, geliştiricilerin animasyon özelliklerini isteğe bağlı bir AnimationSpec parametresiyle özelleştirmelerine olanak tanır.

val alpha: Float by animateFloatAsState(
    targetValue = if (enabled) 1f else 0.5f,
    // Configure the animation duration and easing.
    animationSpec = tween(durationMillis = 300, easing = FastOutSlowInEasing)
)

Farklı animasyon türleri oluşturmak için farklı AnimationSpec türleri vardır.

spring ile fiziğe dayalı animasyon oluşturun

spring, başlangıç ve bitiş değerleri arasında fiziğe dayalı bir animasyon oluşturur. 2 parametre gerekir: dampingRatio ve stiffness.

dampingRatio, yayının ne kadar kıvrımlı olması gerektiğini tanımlar. Varsayılan değer Spring.DampingRatioNoBouncy değeridir.

Şekil 1. Farklı yay sönümleme oranları ayarlanıyor.

stiffness, yayının bitiş değerine doğru ne kadar hızlı ilerlemesi gerektiğini tanımlar. Spring.StiffnessMedium, varsayılan değerdir.

2. Şekil. Farklı bir yay sertliği ayarlanıyor

val value by animateFloatAsState(
    targetValue = 1f,
    animationSpec = spring(
        dampingRatio = Spring.DampingRatioHighBouncy,
        stiffness = Spring.StiffnessMedium
    )
)

spring, animasyonlar arasında hedef değer değiştiğinde hızın sürekliliğini garanti ettiği için kesintileri süreye dayalı AnimationSpec türlerine göre daha sorunsuz şekilde yönetebilir. spring, animate*AsState ve updateTransition gibi birçok animasyon API'si tarafından varsayılan AnimationSpec olarak kullanılır.

Örneğin, aşağıdaki animasyona kullanıcı dokunması tarafından yönlendirilen bir spring yapılandırması uygularsak, animasyon devam ederken animasyon kesintiye uğratıldığında tween kullanımının spring kullanıldığında kadar düzgün yanıt vermediğini görebilirsiniz.

3. Şekil. Animasyon için tween ve spring özelliklerinin ayarlanması ve animasyonun kesintiye uğraması.

tween ile yumuşak geçiş eğrisiyle başlangıç ve bitiş değerleri arasında animasyon oluşturun

tween, bir yumuşak geçiş eğrisi kullanarak belirtilen durationMillis üzerinde başlangıç ve bitiş değerleri arasında animasyon yapar. tween, iki değer arasında olduğu için arasındaki kelimenin kısaltmasıdır.

Animasyonun başlangıcını ertelemek için delayMillis değerini de belirtebilirsiniz.

val value by animateFloatAsState(
    targetValue = 1f,
    animationSpec = tween(
        durationMillis = 300,
        delayMillis = 50,
        easing = LinearOutSlowInEasing
    )
)

Daha fazla bilgi için Yumuşak geçiş bölümüne bakın.

keyframes ile belirli zamanlamalarda belirli değerlere animasyon uygulayın

keyframes, animasyon süresindeki farklı zaman damgalarında belirtilen anlık görüntü değerlerine göre animasyon yapar. Herhangi bir zamanda, animasyon değeri iki animasyon karesi değeri arasında interpolasyona girer. Bu animasyon karelerinin her birinde interpolasyon eğrisini belirlemek için Yumuşak geçiş belirtilebilir.

Değerlerin 0 ms.de ve bu süre boyunca belirtilmesi isteğe bağlıdır. Bu değerleri belirtmezseniz varsayılan olarak animasyonun başlangıç ve bitiş değerlerini kullanırlar.

val value by animateFloatAsState(
    targetValue = 1f,
    animationSpec = keyframes {
        durationMillis = 375
        0.0f at 0 with LinearOutSlowInEasing // for 0-15 ms
        0.2f at 15 with FastOutLinearInEasing // for 15-75 ms
        0.4f at 75 // ms
        0.4f at 225 // ms
    }
)

Animasyonu repeatable ile tekrarlama

repeatable, belirtilen yineleme sayısına ulaşıncaya kadar süreye dayalı bir animasyonu (tween veya keyframes gibi) tekrar tekrar çalıştırır. Animasyonun baştan başlayıp (RepeatMode.Restart) yoksa sondan mı (RepeatMode.Reverse) başlayarak tekrarlanacağını belirtmek için repeatMode parametresini aktarabilirsiniz.

val value by animateFloatAsState(
    targetValue = 1f,
    animationSpec = repeatable(
        iterations = 3,
        animation = tween(durationMillis = 300),
        repeatMode = RepeatMode.Reverse
    )
)

infiniteRepeatable ile bir animasyonu sonsuza kadar tekrarlama

infiniteRepeatable, repeatable gibidir ancak sonsuz sayıda yineleme için tekrarlanır.

val value by animateFloatAsState(
    targetValue = 1f,
    animationSpec = infiniteRepeatable(
        animation = tween(durationMillis = 300),
        repeatMode = RepeatMode.Reverse
    )
)

ComposeTestRule kullanılan testlerde, infiniteRepeatable kullanan animasyonlar çalıştırılmaz. Bileşen, her animasyonlu değerin başlangıç değeri kullanılarak oluşturulacak.

snap ile anında bitiş değerine tutturun

snap, değeri hemen bitiş değerine geçiren özel bir AnimationSpec. Animasyonun başlamasını geciktirmek için delayMillis değerini belirtebilirsiniz.

val value by animateFloatAsState(
    targetValue = 1f,
    animationSpec = snap(delayMillis = 50)
)

Özel yumuşak geçiş işlevi ayarlama

Süreye dayalı AnimationSpec işlemleri (tween veya keyframes gibi) bir animasyonun kesirini ayarlamak için Easing kullanır. Bu sayede animasyon değeri, sabit bir hızda hareket etmek yerine hızlanıp yavaşlar. Kesir, animasyondaki geçerli noktayı belirten 0 (başlangıç) ile 1,0 (bitiş) arasında bir değerdir.

Yumuşak geçiş aslında 0 ile 1,0 arasında kesirli bir değer alan ve hareketli değer döndüren bir işlevdir. Döndürülen değer, aşım veya eksik aşmayı temsil etmek için sınırın dışında olabilir. Aşağıdaki kod gibi özel bir Yumuşak Geçiş oluşturulabilir.

val CustomEasing = Easing { fraction -> fraction * fraction }

@Composable
fun EasingUsage() {
    val value by animateFloatAsState(
        targetValue = 1f,
        animationSpec = tween(
            durationMillis = 300,
            easing = CustomEasing
        )
    )
    // ……
}

Oluşturma, çoğu kullanım alanını kapsayan çeşitli yerleşik Easing işlevleri sağlar. Senaryonuza bağlı olarak yumuşak geçiş kullanımı hakkında daha fazla bilgi için Hız - Materyal Tasarım bölümüne bakın.

  • FastOutSlowInEasing
  • LinearOutSlowInEasing
  • FastOutLinearEasing
  • LinearEasing
  • CubicBezierEasing
  • Diğerlerini göster

Özel veri türlerini, AnimationVector öğesine ve buradan dönüşüm gerçekleştirerek canlandırın

Compose animasyon API'lerinin çoğu Float, Color, Dp ve diğer temel veri türlerini varsayılan olarak animasyon değerleri olarak destekler. Ancak bazen özel olanlar da dahil olmak üzere diğer veri türlerini canlandırmanız gerekir. Animasyon sırasında, herhangi bir animasyon değeri AnimationVector olarak gösterilir. Temel animasyon sisteminin bunları eşit şekilde işleyebilmesi için değer, AnimationVector değerine ve karşılık gelen bir TwoWayConverter tarafından da AnimationVector değerine dönüştürülür. Örneğin, bir Int, tek bir kayan değer içeren bir AnimationVector1D olarak temsil edilir. Int için TwoWayConverter şöyle görünüyor:

val IntToVector: TwoWayConverter<Int, AnimationVector1D> =
    TwoWayConverter({ AnimationVector1D(it.toFloat()) }, { it.value.toInt() })

Color, kırmızı, yeşil, mavi ve alfa olmak üzere 4 değerden oluşur. Bu nedenle Color, 4 kayan değer içeren bir AnimationVector4D değerine dönüştürülür. Böylece, animasyonlarda kullanılan her veri türü, boyuta bağlı olarak AnimationVector1D, AnimationVector2D, AnimationVector3D veya AnimationVector4D'ye dönüştürülür. Bu, nesnenin farklı bileşenlerinin, her birinin kendi hız takibine sahip olacak şekilde bağımsız olarak canlandırılmasına olanak tanır. Temel veri türleri için yerleşik dönüştürücülere, Color.VectorConverter veya Dp.VectorConverter gibi dönüştürücüler kullanılarak erişilebilir.

Animasyon değeri olarak yeni bir veri türü için destek eklemek istediğinizde kendi TwoWayConverter öğenizi oluşturabilir ve API'ye sağlayabilirsiniz. Örneğin, özel veri türünüzü şu şekilde canlandırmak için animateValueAsState kullanabilirsiniz:

data class MySize(val width: Dp, val height: Dp)

@Composable
fun MyAnimation(targetSize: MySize) {
    val animSize: MySize by animateValueAsState(
        targetSize,
        TwoWayConverter(
            convertToVector = { size: MySize ->
                // Extract a float value from each of the `Dp` fields.
                AnimationVector2D(size.width.value, size.height.value)
            },
            convertFromVector = { vector: AnimationVector2D ->
                MySize(vector.v1.dp, vector.v2.dp)
            }
        )
    )
}

Aşağıdaki listede bazı yerleşik VectorConverter'ler bulunmaktadır: