शेयर किए गए एलिमेंट के ट्रांज़िशन को पसंद के मुताबिक बनाएं

शेयर किए गए एलिमेंट ट्रांज़िशन ऐनिमेशन के चलने के तरीके को पसंद के मुताबिक बनाने के लिए, कुछ शेयर किए गए एलिमेंट के ट्रांज़िशन का तरीका बदलने के लिए, इस्तेमाल किए जा सकने वाले पैरामीटर.

ऐनिमेशन की खास बातें

साइज़ और पोज़िशन अडजस्ट करने के लिए इस्तेमाल होने वाले ऐनिमेशन स्पेसिफ़िकेशन में बदलाव करने के लिए, Modifier.sharedElement() पर कोई दूसरा boundsTransform पैरामीटर तय करें. इससे, शुरुआती Rect पोज़िशन और टारगेट Rect पोज़िशन की जानकारी मिलती है.

उदाहरण के लिए, पिछले उदाहरण में दिए गए टेक्स्ट को चाप के साथ मूव करना मोशन, तो keyframes की खास जानकारी का इस्तेमाल करने के लिए boundsTransform पैरामीटर तय करें:

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
    )
)

किसी भी AnimationSpec का इस्तेमाल किया जा सकता है. इस उदाहरण में, keyframes स्पेसिफ़िकेशन का इस्तेमाल किया गया है.

पहली इमेज. अलग-अलग boundsTransform पैरामीटर
को दिखाने वाला उदाहरण

साइज़ बदलने वाला मोड

शेयर की गई दो सीमाओं के बीच ऐनिमेट करते समय, resizeMode पैरामीटर सेट किया जा सकता है RemeasureToBounds या ScaleToBounds को. इस पैरामीटर से तय होता है कि शेयर्ड एलिमेंट की दो स्थितियों के बीच ट्रांज़िशन. पहले ScaleToBounds लुकअहेड (या टारगेट) कंस्ट्रेंट के साथ चाइल्ड लेआउट को मेज़र करता है. इसके बाद, बच्चे के स्थिर लेआउट को बढ़ाया गया है, ताकि वह शेयर की गई सीमाओं में फ़िट हो सके. ScaleToBounds को "ग्राफ़िकल स्केल" के तौर पर देखा जा सकता है राज्यों के बीच है.

वहीं, RemeasureToBounds इसके चाइल्ड लेआउट को फिर से मेज़र और लेआउट करता है टारगेट साइज़ के आधार पर, ऐनिमेशन वाले तय कंस्ट्रेंट के साथ sharedBounds. कॉन्टेंट बनाने फिर से मेज़रमेंट, सीमाओं के साइज़ में बदलाव से ट्रिगर होता है. इससे हर फ़्रेम को बेहतर तरीके से दिखा सकते हैं.

Text कंपोज़ेबल के लिए, ScaleToBounds का सुझाव दिया जाता है. ऐसा इसलिए, क्योंकि इससे रिलेआउट नहीं होगा और टेक्स्ट को अलग-अलग लाइन पर रीफ़्लो करने की सुविधा मिलती है. अलग-अलग पहलुओं वाली सीमाओं के लिए अनुपात होता है और अगर आपको दो साझा तत्वों के बीच तरल पदार्थ जारी रखना है, RemeasureToBounds का सुझाव दिया जाता है.

साइज़ बदलने वाले दो मोड के बीच का अंतर, यहां दिए गए उदाहरणों में देखा जा सकता है:

ScaleToBounds

RemeasureToBounds

सीधे फ़ाइनल लेआउट पर जाएं

डिफ़ॉल्ट रूप से, दो लेआउट के बीच ट्रांज़िशन करते समय, लेआउट का साइज़ ऐनिमेट हो जाता है अपने शुरुआती और आखिरी स्थिति के बीच सेट कर सकती है. ऐसा करने से, ऐनिमेट करना ज़रुरी है, जैसे कि टेक्स्ट.

इस उदाहरण में, "Lorem Ipsum" के ब्यौरे वाला टेक्स्ट दिखाया गया है प्रवेश कर रहा है स्क्रीन को दो अलग-अलग तरीक़ों से देख सकते हैं. पहला उदाहरण, टेक्स्ट जैसे ही रीफ़्लो होता है जैसे-जैसे कंटेनर का साइज़ बढ़ता है, वैसे-वैसे उसमें शामिल होता है. दूसरे उदाहरण में, टेक्स्ट रीफ़्लो को बढ़ाया जा सकता है. Modifier.skipToLookaheadSize() को जोड़ने से, रीफ़्लो नहीं होता जैसे-जैसे यह बढ़ती है.

कोई Modifier.skipToLookahead() नहीं - "Lorem Ipsum" देखें टेक्स्ट रीफ़्लोइंग

Modifier.skipToLookahead() - "Lorem Ipsum" देखें ऐनिमेशन की शुरुआत में ही टेक्स्ट अपनी आखिरी स्थिति बनाए रखता है

क्लिप और ओवरले

Compose में शेयर किए जाने वाले एलिमेंट बनाते समय एक अहम कॉन्सेप्ट यह है कि अलग-अलग कंपोज़ेबल के बीच शेयर करने के लिए, कंपोज़ेबल को ऐसी लेयर ओवरले में ले जाया जाता है जब ट्रांज़िशन शुरू हो गंतव्य में यह मेल खाता है. इसका असर यह होता है कि यह पैरंट बाउंड और इसके लेयर ट्रांसफ़ॉर्मेशन (उदाहरण के लिए, ऐल्फ़ा और स्केल).

ट्रांज़िशन होने के बाद, यह शेयर नहीं किए जाने वाले दूसरे यूज़र इंटरफ़ेस (यूआई) एलिमेंट के ऊपर रेंडर होगा खत्म हो जाने पर, एलिमेंट को ओवरले से उसके अपने DrawScope में छोड़ दिया जाएगा.

शेयर किए गए किसी एलिमेंट को किसी आकार से क्लिप करने के लिए, स्टैंडर्ड Modifier.clip() का इस्तेमाल करें फ़ंक्शन का इस्तेमाल करना होगा. इसे sharedElement() के बाद लगाएं:

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
)

अगर आपको यह पक्का करने की ज़रूरत हो कि शेयर किया गया एलिमेंट कभी भी पैरंट के बाहर रेंडर नहीं होता हो कंटेनर, sharedElement() पर clipInOverlayDuringTransition सेट किया जा सकता है. इन्होंने बदलाव किया है डिफ़ॉल्ट तौर पर, नेस्ट की गई शेयर की गई सीमाओं के लिए clipInOverlayDuringTransition, क्लिप का इस्तेमाल करता है पैरंट sharedBounds() का पाथ.

खास यूज़र इंटरफ़ेस (यूआई) एलिमेंट को बनाए रखने के लिए, जैसे कि बॉटम बार या फ़्लोटिंग ऐक्शन बटन, शेयर किए गए एलीमेंट के ट्रांज़िशन के दौरान हमेशा सबसे ऊपर रहता है, इसका इस्तेमाल करें Modifier.renderInSharedTransitionScopeOverlay(). डिफ़ॉल्ट रूप से, यह मॉडिफ़ायर तब तक ओवरले में कॉन्टेंट बनाए रखता है, जब तक फ़ाइल शेयर की जाती है ट्रांज़िशन चालू है.

उदाहरण के लिए, JetSनैक में, BottomAppBar को शेयर किए जा सकने वाले एलिमेंट को तब तक शेयर नहीं किया जा सकता, जब तक कि स्क्रीन दिखाई न दे. मॉडिफ़ायर जोड़ना कंपोज़ेबल में शॉर्ट वीडियो की क्वालिटी बनी रहती है.

Modifier.renderInSharedTransitionScopeOverlay() के बिना

Modifier.renderInSharedTransitionScopeOverlay() से साइन इन किया गया

कभी-कभी हो सकता है कि आप शेयर नहीं किए गए अपने कंपोज़ेबल को ऐनिमेट करना चाहें ट्रांज़िशन से पहले, अन्य कंपोज़ेबल में सबसे ऊपर बने रहें. ऐसे मामलों में, ऐनिमेट करने के लिए renderInSharedTransitionScopeOverlay().animateEnterExit() शेयर किए गए एलिमेंट ट्रांज़िशन के चलने के बाद, कंपोज़ेबल.

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

दूसरी इमेज.ऐनिमेशन के ट्रांज़िशन के दौरान स्क्रीन पर सबसे नीचे मौजूद ऐप्लिकेशन बार, अंदर और बाहर स्लाइड हो रहा है

बहुत कम मामलों में तब ऐसा होता है, जब आप चाहें कि आपका शेयर किया गया एलिमेंट किसी ओवरले से, sharedElement() पर renderInOverlayDuringTransition सेट किया जा सकता है गलत पर सेट करें.

शेयर किए गए एलिमेंट के साइज़ में बदलाव होने पर, सिबलिंग लेआउट की सूचना दें

डिफ़ॉल्ट रूप से, sharedBounds() और sharedElement(), माता-पिता को सूचना नहीं देते हैं किसी भी साइज़ का कंटेनर, लेआउट ट्रांज़िशन के साथ बदलता है.

पैरंट कंटेनर के साइज़ में बदलाव होने पर, उसे ट्रांज़िशन के तौर पर लागू करने के लिए, placeHolderSize पैरामीटर को PlaceHolderSize.animatedSize में बदलें. करना इसलिए आइटम की संख्या बढ़ने या सिकुड़ने लगती है. लेआउट के अन्य सभी आइटम इसका जवाब देते हैं बदलाव.

PlaceholderSize.contentSize (डिफ़ॉल्ट)

PlaceholderSize.animatedSize

(ध्यान दें कि एक आइटम के बढ़ने की वजह से, सूची के दूसरे आइटम किस तरह नीचे की ओर मूव होते हैं)