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 özelliklerini değiştirmek üzere Modifier.sharedElement() için farklı bir boundsTransform parametresi belirtin. Bu, ilk Rect konumunu ve hedef Rect konumunu sağlar.

Örneğin, önceki örnekte verilen metni bir yay ile hareket edecek şekilde ayarlamak için motion, keyframes spesifikasyonu kullanmak için 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 paylaşılan sınır arasında animasyon oluştururken resizeMode parametresini ayarlayabilirsiniz RemeasureToBounds veya ScaleToBounds değerine ayarlayın. Bu parametre, paylaşılan öğe, iki durum arasında geçiş yapar. Önce ScaleToBounds ileri tarihli (veya hedef) kısıtlamalarla alt düzeni ö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 alt öğe düzenini yeniden ölçüp yeniden düzenler. Hedef boyuta göre sabit, animasyonlu kısıtlamalarla sharedBounds. Yeniden ölçüm, sınırların boyutu değiştiğinde tetiklenir. Bu durum her karede gerçekleşebilir.

Text composable'da geçişi önleyeceği için ScaleToBounds önerilir metinlerin farklı satırlara yeniden düzenlenmesinden ibarettir. 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. Metin gibi içerikleri animasyonlu hale getirirken bu istenmeyen bir davranış olabilir.

Aşağıdaki örnekte "Lorem Ipsum" açıklama metni gösterilmektedir giriş iki şekilde kontrol edebilirsiniz. İlk örnekte metnin akışı ve büyük bir yer girdikçe, metin kapsayıcı boyutu büyüdükçe yeniden düzenlemenizi sağlar. 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" öğesine dikkat edin metin, animasyonun başında son durumunu korur

Klip ve yer paylaşımlı

Oluşturma'da paylaşılan öğeler oluştururken dikkat edilmesi gereken önemli bir nokta, öğelerin farklı kompozisyonlar arasında paylaşılabilmesi 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.

Geçiş tamamlandıktan sonra bu dosya, paylaşılmayan diğer kullanıcı arayüzü öğelerinin üzerinde oluşturulur. sona erdiğinde, öğe yer paylaşımından kendi DrawScope öğesine atlanır.

Paylaşılan bir öğeyi şekle kırpmak için standart Modifier.clip() kullanın 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 bir üst öğe dışında oluşturulmadığından emin olmanız gerekiyorsa kapsayıcısı için sharedElement() üzerinde clipInOverlayDuringTransition değerini ayarlayabilirsiniz. Ölçüt varsayılan olarak, iç içe yerleştirilmiş paylaşılan sınırlar için clipInOverlayDuringTransition klibi kullanır üst sharedBounds() içindeki yol.

Alt çubuk veya kayan işlem gibi belirli kullanıcı arayüzü öğelerinin tutulmasını desteklemek için düğmesi, paylaşılan öğe geçişi sırasında her zaman üsttedir, Modifier.renderInSharedTransitionScopeOverlay(). 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'te BottomAppBar öğesinin, grafiğin paylaşılan öğe eklemeye devam edebilirsiniz. Değiştirici ekleme yüksekte kalmasını sağlar.

Modifier.renderInSharedTransitionScopeOverlay() olmadan

Modifier.renderInSharedTransitionScopeOverlay() ile

Bazen paylaşılmayan composable'ınızın hem animasyon önce diğer composable'ların üzerinde duracağını düşünüyor. 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şi sırasında içeri ve dışarı kayan Alt Uygulama çubuğu

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.

Geçiş yaparken üst kapsayıcıya boyut değişikliklerini yaymak için placeHolderSize parametresini PlaceHolderSize.animatedSize olarak değiştirin. Yapmak ve dolayısıyla öğenin büyümesine veya küçülmesine neden olur. Düzendeki diğer tüm öğeler değiştirmek istiyorum.

PlaceholderSize.contentSize (varsayılan)

PlaceholderSize.animatedSize

(Listedeki diğer öğelerin, artan bir öğeye yanıt olarak nasıl düştüğüne dikkat edin)