Paylaşılan öğe geçişini özelleştir

Paylaşılan öğe geçiş animasyonunun nasıl çalışacağını özelleştirmek için paylaşılan öğelerin geçiş şeklini değiştirmek üzere kullanılabilecek birkaç parametre vardır.

Animasyon özellikleri

Boyut ve konum hareketi için kullanılan animasyon spesifikasyonunu değiştirmek üzere Modifier.sharedElement() üzerinde farklı bir boundsTransform parametresi belirtebilirsiniz. Bu, ilk Rect konumunu ve hedef Rect konumunu sağlar.

Örneğin, önceki örnekteki metnin yay hareketiyle hareket etmesini sağlamak için keyframes spesifikasyonu kullanmak üzere boundsTransform parametresini belirtin:

val textBoundsTransform = BoundsTransform { initialBounds, targetBounds ->
    keyframes {
        durationMillis = boundsAnimationDurationMillis
        initialBounds at 0 using ArcMode.ArcBelow using FastOutSlowInEasing
        targetBounds at boundsAnimationDurationMillis
    }
}
Text(
    "Cupcake", fontSize = 28.sp,
    modifier = Modifier.sharedBounds(
        rememberSharedContentState(key = "title"),
        animatedVisibilityScope = animatedVisibilityScope,
        boundsTransform = textBoundsTransform
    )
)

Herhangi bir AnimationSpec kullanabilirsiniz. Bu örnekte keyframes spesifikasyonu kullanılmaktadır.

Şekil 1. Farklı boundsTransform parametrelerini
gösteren örnek

Yeniden boyutlandırma modu

İki ortak sınır arasında animasyon oluştururken resizeMode parametresini RemeasureToBounds veya ScaleToBounds olarak ayarlayabilirsiniz. Bu parametre, paylaşılan öğenin iki durum arasında nasıl geçiş yapacağını belirler. ScaleToBounds önce alt düzeni ileriye dönük (veya hedef) kısıtlamalarla ölçer. Ardından, alt öğenin kararlı düzeni, paylaşılan sınırlara sığacak şekilde ölçeklendirilir. ScaleToBounds, eyaletler arasındaki "grafik ölçek" olarak düşünülebilir.

RemeasureToBounds ise sharedBounds'un alt düzenini hedef boyuta göre animasyonlu sabit kısıtlamalarla yeniden ölçer ve yeniden düzenler. Yeniden ölçüm, sınırların boyutu değiştiğinde tetiklenir. Bu durum her karede gerçekleşebilir.

Text bileşenleri için metnin farklı satırlara yeniden düzenlenmesini ve yeniden akışını önlediğinden ScaleToBounds önerilir. Farklı en boy oranına sahip sınırlar için ve paylaşılan iki öğe arasında sorunsuz bir devamlılık istiyorsanız RemeasureToBounds önerilir.

İki yeniden boyutlandırma modu arasındaki fark aşağıdaki örneklerde görülebilir:

ScaleToBounds

RemeasureToBounds

Son düzene atlama

Varsayılan olarak, iki düzen arasında geçiş yapılırken düzen boyutu, başlangıç ve son durumu arasında animasyonlu olarak değişir. Bu, metin gibi içerikleri animasyonlu hale getirirken istenmeyen bir davranış olabilir.

Aşağıdaki örnekte, "Lorem Ipsum" açıklama metninin ekrana iki farklı şekilde nasıl girdiği gösterilmektedir. İlk örnekte, kapsayıcı büyüdükçe metin girerken yeniden akışı sağlanır. İkinci örnekte ise metin büyüdükçe yeniden akışı sağlanmaz. Modifier.skipToLookaheadSize() eklemek, boyutu büyüdükçe yeniden akışı önler.

Modifier.skipToLookahead() yok - "Lorem Ipsum" metninin yeniden akışını fark edin

Modifier.skipToLookahead() - "Lorem Ipsum" metninin animasyonun başlangıcında son durumunu koruduğuna dikkat edin

Klip ve yer paylaşımları

Oluşturma'da paylaşılan öğeler oluştururken dikkat edilmesi gereken önemli bir nokta, farklı kompozisyonlar arasında paylaşılabilmeleri için kompozisyonun oluşturulmasının, hedefteki eşleşmesine geçiş yapıldığında bir katman yer paylaşımına yükseltilmesidir. Bunun etkisi, üst öğenin sınırlarını ve katman dönüşümlerini (ör. alfa ve ölçek) atlamasıdır.

Paylaşılmayan diğer kullanıcı arayüzü öğelerinin üzerinde oluşturulur. Geçiş tamamlandığında öğe, yer paylaşımından kendi DrawScope alanına bırakılır.

Paylaşılan bir öğeyi bir şekle kırpmak için standart Modifier.clip() işlevini kullanın. sharedElement() işaretinin sonuna yerleştirin:

Image(
    painter = painterResource(id = R.drawable.cupcake),
    contentDescription = "Cupcake",
    modifier = Modifier
        .size(100.dp)
        .sharedElement(
            rememberSharedContentState(key = "image"),
            animatedVisibilityScope = this@AnimatedContent
        )
        .clip(RoundedCornerShape(16.dp)),
    contentScale = ContentScale.Crop
)

Paylaşılan bir öğenin hiçbir zaman üst kapsayıcı dışında oluşturulmadığından emin olmanız gerekiyorsa clipInOverlayDuringTransition öğesini sharedElement() olarak ayarlayabilirsiniz. Varsayılan olarak, iç içe yerleştirilmiş paylaşılan sınırlar için clipInOverlayDuringTransition, sharedBounds() üst öğesindeki klip yolunu kullanır.

Alt çubuk veya yüzen işlem düğmesi gibi belirli kullanıcı arayüzü öğelerinin paylaşılan öğe geçişi sırasında her zaman en üstte kalmasını desteklemek için Modifier.renderInSharedTransitionScopeOverlay() öğesini kullanın. Bu değiştirici, varsayılan olarak paylaşılan geçiş etkin olduğu sırada içeriği yer paylaşımında tutar.

Örneğin, Jetsnack'ta BottomAppBar, ekran görünmeyene kadar paylaşılan öğenin üzerine yerleştirilmelidir. Değiştiriciyi bileşime eklemek, bileşimin yüksekliğini korur.

Modifier.renderInSharedTransitionScopeOverlay() olmadan

Modifier.renderInSharedTransitionScopeOverlay() ile

Bazen, paylaşılmayan bir bileşeninizin animasyonla kaybolmasını ve geçişten önce diğer bileşenlerin üzerinde kalmasını isteyebilirsiniz. Bu gibi durumlarda, paylaşılan öğe geçişi çalışırken bileşimi dışarı doğru animasyonlu olarak göstermek için renderInSharedTransitionScopeOverlay().animateEnterExit() öğesini kullanın:

JetsnackBottomBar(
    modifier = Modifier
        .renderInSharedTransitionScopeOverlay(
            zIndexInOverlay = 1f,
        )
        .animateEnterExit(
            enter = fadeIn() + slideInVertically {
                it
            },
            exit = fadeOut() + slideOutVertically {
                it
            }
        )
)

Şekil 2. Animasyon geçişleri sırasında alt uygulama çubuğunun kayması

Paylaşılan öğenizin yer paylaşımında oluşturulmamasını istediğiniz nadir durumlarda, sharedElement() üzerindeki renderInOverlayDuringTransition özelliğini false olarak ayarlayabilirsiniz.

Paylaşılan öğe boyutunda yapılan değişikliklerle ilgili olarak kardeş düzenleri bilgilendirme

Varsayılan olarak sharedBounds() ve sharedElement(), düzen geçişleri sırasında üst kapsayıcıya boyut değişiklikleri hakkında bildirim göndermez.

Boyut değişikliklerinin geçiş sırasında üst kapsayıcıya yayılması için placeHolderSize parametresini PlaceHolderSize.animatedSize olarak değiştirin. Bu işlem, öğenin büyümesine veya küçülmesine neden olur. Düzendeki diğer tüm öğeler bu değişikliğe yanıt verir.

PlaceholderSize.contentSize (varsayılan)

PlaceholderSize.animatedSize

(Listedeki diğer öğelerin, büyüyen öğeye yanıt olarak nasıl aşağı doğru hareket ettiğine dikkat edin)