शेयर किए गए एलिमेंट के ट्रांज़िशन ऐनिमेशन को पसंद के मुताबिक बनाने के लिए, कुछ पैरामीटर का इस्तेमाल किया जा सकता है. इनकी मदद से, शेयर किए गए एलिमेंट के ट्रांज़िशन के तरीके में बदलाव किया जा सकता है.
ऐनिमेशन की जानकारी
साइज़ और पोज़िशन में बदलाव के लिए इस्तेमाल किए गए ऐनिमेशन स्पेसिफ़िकेशन को बदलने के लिए, 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 का इस्तेमाल उन बाउंड के लिए किया जाता है जिनकी चौड़ाई-ऊंचाई का अनुपात अलग-अलग होता है. साथ ही, इसका इस्तेमाल तब भी किया जाता है, जब आपको शेयर किए गए दो एलिमेंट के बीच फ़्लूड ट्रांज़िशन चाहिए होता है.
रीसाइज़ करने के दो मोड के बीच का अंतर, यहां दिए गए उदाहरणों में देखा जा सकता है:
|
|
|---|---|
सीधे फ़ाइनल लेआउट पर जाएं
डिफ़ॉल्ट रूप से, दो लेआउट के बीच ट्रांज़िशन करते समय, लेआउट का साइज़ अपनी शुरुआती और आखिरी स्थिति के बीच ऐनिमेशन करता है. टेक्स्ट जैसे कॉन्टेंट को ऐनिमेट करते समय, ऐसा हो सकता है कि यह अनचाहा व्यवहार हो.
इस उदाहरण में, "Lorem Ipsum" टेक्स्ट को दो अलग-अलग तरीकों से स्क्रीन पर आते हुए दिखाया गया है. पहले उदाहरण में, कंटेनर का साइज़ बढ़ने पर टेक्स्ट फिर से फ़्लो होता है. दूसरे उदाहरण में, टेक्स्ट के बढ़ने पर वह अपने-आप नहीं बदलता. Modifier.skipToLookaheadSize() जोड़ने से, लेआउट में बदलाव नहीं होता, क्योंकि यह बढ़ता रहता है.
कोई |
|
|---|---|
क्लिप और ओवरले
शेयर किए गए एलिमेंट को अलग-अलग कंपोज़ेबल के बीच शेयर करने के लिए, जब डेस्टिनेशन में ट्रांज़िशन शुरू होता है, तब कंपोज़ेबल की रेंडरिंग को लेयर ओवरले में बदल दिया जाता है. इसका असर यह होगा कि यह पैरंट के दायरे से बाहर निकल जाएगा और इसकी लेयर ट्रांसफ़ॉर्मेशन (उदाहरण के लिए, ऐल्फ़ा और स्केल) पर भी इसका असर नहीं पड़ेगा.
यह शेयर नहीं किए गए अन्य यूज़र इंटरफ़ेस (यूआई) एलिमेंट के ऊपर रेंडर होगा. ट्रांज़िशन पूरा होने के बाद, एलिमेंट को ओवरले से हटाकर उसके 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() का इस्तेमाल करें. जैसे, बॉटम बार या फ़्लोटिंग ऐक्शन बटन. डिफ़ॉल्ट रूप से, यह मॉडिफ़ायर, शेयर की गई ट्रांज़िशन चालू रहने के दौरान कॉन्टेंट को ओवरले में रखता है.
उदाहरण के लिए, Jetsnack में BottomAppBar को शेयर किए गए एलिमेंट के ऊपर तब तक रखना होगा, जब तक स्क्रीन नहीं दिख जाती. मॉडिफ़ायर को कॉम्पोज़ेबल में जोड़ने से, यह ऊपर की ओर दिखता है.
|
|
|---|---|
ऐसा हो सकता है कि आपको ट्रांज़िशन से पहले, अपने नॉन-शेयर्ड कंपोज़ेबल को ऐनिमेट करके हटाना हो. साथ ही, उसे अन्य कंपोज़ेबल के ऊपर रखना हो. ऐसे मामलों में, शेयर किए गए एलिमेंट के ट्रांज़िशन के दौरान कंपोज़ेबल को ऐनिमेट करने के लिए, renderInSharedTransitionScopeOverlay().animateEnterExit() का इस्तेमाल करें:
JetsnackBottomBar( modifier = Modifier .renderInSharedTransitionScopeOverlay( zIndexInOverlay = 1f, ) .animateEnterExit( enter = fadeIn() + slideInVertically { it }, exit = fadeOut() + slideOutVertically { it } ) )
अगर आपको शेयर किए गए एलिमेंट को ओवरले में रेंडर नहीं करना है, तो sharedElement() पर renderInOverlayDuringTransition को false पर सेट करें.
शेयर किए गए एलिमेंट के साइज़ में हुए बदलावों के बारे में, मिलते-जुलते लेआउट को सूचना दें
डिफ़ॉल्ट रूप से, लेआउट ट्रांज़िशन के दौरान साइज़ में होने वाले बदलावों के बारे में sharedBounds() और sharedElement(), पैरंट कंटेनर को सूचना नहीं देते हैं.
ट्रांज़िशन के दौरान, साइज़ में हुए बदलावों को पैरंट कंटेनर में लागू करने के लिए, placeHolderSize पैरामीटर को PlaceHolderSize.animatedSize में बदलें. ऐसा करने से, आइटम का साइज़ बढ़ता या घटता है. लेआउट में मौजूद अन्य सभी आइटम, बदलाव के हिसाब से काम करते हैं.
|
(ध्यान दें कि एक आइटम के बढ़ने पर, सूची में मौजूद अन्य आइटम नीचे की ओर चले जाते हैं) |
|---|---|