1. शुरू करने से पहले
यह कोडलैब, Kotlin में ऐडवांस Android कोर्स का हिस्सा है. अगर इस कोर्स के कोडलैब को क्रम से पूरा किया जाता है, तो आपको सबसे ज़्यादा फ़ायदा मिलेगा. हालांकि, ऐसा करना ज़रूरी नहीं है. कोर्स के सभी कोडलब, Kotlin में ऐडवांस Android कोडलब के लैंडिंग पेज पर दिए गए हैं.
MotionLayout एक ऐसी लाइब्रेरी है जिसकी मदद से, अपने Android ऐप्लिकेशन में बेहतर मोशन जोड़ा जा सकता है. यह ConstraintLayout, पर आधारित है. इसकी मदद से, ConstraintLayout का इस्तेमाल करके बनाई गई किसी भी चीज़ को ऐनिमेट किया जा सकता है.
MotionLayout का इस्तेमाल करके, एक साथ कई व्यू की जगह, साइज़, दिखने की स्थिति, ऐल्फ़ा, रंग, ऊंचाई, रोटेशन, और अन्य एट्रिब्यूट में ऐनिमेशन जोड़ा जा सकता है. डिक्लेरेटिव एक्सएमएल का इस्तेमाल करके, कई व्यू वाली कोऑर्डिनेटेड ऐनिमेशन बनाई जा सकती हैं. इन्हें कोड में बनाना मुश्किल होता है.
ऐनिमेशन, ऐप्लिकेशन इस्तेमाल करने के अनुभव को बेहतर बनाने का एक शानदार तरीका है. ऐनिमेशन का इस्तेमाल इन कामों के लिए किया जा सकता है:
- बदलाव दिखाएं—स्टेट के बीच ऐनिमेशन दिखाने से, उपयोगकर्ता को आपके यूज़र इंटरफ़ेस (यूआई) में हुए बदलावों को आसानी से ट्रैक करने में मदद मिलती है.
- ध्यान खींचना—ज़रूरी यूज़र इंटरफ़ेस (यूआई) एलिमेंट पर ध्यान खींचने के लिए, ऐनिमेशन का इस्तेमाल करें.
- खूबसूरत डिज़ाइन बनाएं—डिज़ाइन में मोशन का सही इस्तेमाल करने से, ऐप्लिकेशन बेहतर दिखते हैं.
ज़रूरी शर्तें
इस कोडलैब को उन डेवलपर के लिए डिज़ाइन किया गया है जिनके पास Android ऐप्लिकेशन डेवलपमेंट का कुछ अनुभव है. इस कोडलैब को पूरा करने से पहले, आपको ये काम करने चाहिए:
- Android Studio का इस्तेमाल करके, ऐक्टिविटी और बुनियादी लेआउट वाला ऐप्लिकेशन बनाने का तरीका जानें. साथ ही, इसे किसी डिवाइस या एम्युलेटर पर चलाने का तरीका जानें.
ConstraintLayoutके बारे में जानें.ConstraintLayoutके बारे में ज़्यादा जानने के लिए, ConstraintLayout कोडलैब पढ़ें.
आपको क्या करना होगा
ConstraintSetsऔरMotionLayoutकी मदद से ऐनिमेशन तय करना- ड्रैग इवेंट के आधार पर ऐनिमेशन बनाना
KeyPositionकी मदद से ऐनिमेशन बदलनाKeyAttributeकी मदद से एट्रिब्यूट बदलना- कोड की मदद से ऐनिमेशन चलाना
MotionLayoutकी मदद से, छोटे किए जा सकने वाले हेडर को ऐनिमेट करना
आपको इन चीज़ों की ज़रूरत होगी
- Android Studio 4.0 (
MotionLayoutएडिटर सिर्फ़ Android Studio के इस वर्शन के साथ काम करता है.)
2. शुरू करें
उदाहरण के तौर पर दिए गए ऐप्लिकेशन को डाउनलोड करने के लिए, इनमें से कोई एक तरीका अपनाएं:
... या कमांड लाइन से GitHub रिपॉज़िटरी को क्लोन करें. इसके लिए, यह कमांड इस्तेमाल करें:
$ git clone https://github.com/googlecodelabs/motionlayout.git
3. MotionLayout की मदद से ऐनिमेशन बनाना
सबसे पहले, आपको एक ऐसा ऐनिमेशन बनाना होगा जो उपयोगकर्ता के क्लिक करने पर, व्यू को स्क्रीन के सबसे ऊपर से सबसे नीचे ले जाए.
स्टार्टर कोड से ऐनिमेशन बनाने के लिए, आपको इन मुख्य चीज़ों की ज़रूरत होगी:
MotionLayout,,ConstraintLayoutकी सबक्लास है. आपकोMotionLayoutटैग के अंदर, ऐनिमेशन वाले सभी व्यू तय करने होते हैं.MotionScene,, जो एक एक्सएमएल फ़ाइल है. इसमेंMotionLayout.के लिए ऐनिमेशन के बारे में बताया गया हैTransition,,MotionSceneका हिस्सा होता है. इसमें ऐनिमेशन की अवधि, ट्रिगर, और व्यू को मूव करने के तरीके के बारे में जानकारी दी जाती है.- एक
ConstraintSet, जो ट्रांज़िशन की start और end, दोनों सीमाओं के बारे में बताता है.
आइए, एक-एक करके इन सभी के बारे में जानें. सबसे पहले, MotionLayout के बारे में जानते हैं.
पहला चरण: मौजूदा कोड के बारे में जानकारी हासिल करना
MotionLayout, ConstraintLayout की सबक्लास है. इसलिए, इसमें ऐनिमेशन जोड़ने के साथ-साथ, ConstraintLayout की सभी सुविधाएं मिलती हैं. MotionLayout का इस्तेमाल करने के लिए, आपको MotionLayout व्यू जोड़ना होगा. यह व्यू, उस जगह पर जोड़ें जहां आपको ConstraintLayout. का इस्तेमाल करना है
res/layoutमें,activity_step1.xml.खोलें यहां आपके पास एकConstraintLayoutहै, जिसमें एक स्टार काImageViewहै. इसमें एक रंग लगाया गया है.
activity_step1.xml
<!-- initial code -->
<androidx.constraintlayout.widget.ConstraintLayout
...
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<ImageView
android:id="@+id/red_star"
...
/>
</androidx.constraintlayout.motion.widget.MotionLayout>
इस ConstraintLayout पर कोई पाबंदी नहीं है. इसलिए, अगर आपको अभी ऐप्लिकेशन चलाना है, तो आपको स्टार डिसप्ले बिना किसी पाबंदी के दिखेगा. इसका मतलब है कि उन्हें किसी अनजान जगह पर रखा जाएगा. Android Studio, आपको कॉन्स्ट्रेंट के न होने के बारे में चेतावनी देगा.
दूसरा चरण: मोशन लेआउट में बदलना
MotionLayout, का इस्तेमाल करके ऐनिमेशन बनाने के लिए, आपको ConstraintLayout को MotionLayout में बदलना होगा.
मोशन सीन का इस्तेमाल करने के लिए, लेआउट को मोशन सीन पर पॉइंट करना होगा.
- इसके लिए, डिज़ाइन सर्फ़ेस खोलें. Android Studio 4.0 में, लेआउट एक्सएमएल फ़ाइल देखते समय सबसे ऊपर दाईं ओर मौजूद स्प्लिट या डिज़ाइन आइकॉन का इस्तेमाल करके, डिज़ाइन सर्फ़ेस खोला जाता है.

- डिज़ाइन सरफेस खोलने के बाद, झलक पर राइट क्लिक करें और MotionLayout में बदलें को चुनें.

इससे ConstraintLayout टैग को MotionLayout टैग से बदल दिया जाता है. साथ ही, MotionLayout टैग में एक motion:layoutDescription जोड़ दिया जाता है, जो @xml/activity_step1_scene. पर ले जाता है
activity_step1**.xml**
<!-- explore motion:layoutDescription="@xml/activity_step1_scene" -->
<androidx.constraintlayout.motion.widget.MotionLayout
...
motion:layoutDescription="@xml/activity_step1_scene">
मोशन सीन एक एक्सएमएल फ़ाइल होती है. इसमें MotionLayout में मौजूद ऐनिमेशन के बारे में जानकारी होती है.
MotionLayout में बदलने के बाद, डिज़ाइन सर्फ़ेस पर मोशन एडिटर दिखेगा

मोशन एडिटर में, यूज़र इंटरफ़ेस (यूआई) के तीन नए एलिमेंट जोड़े गए हैं:
- खास जानकारी – यह एक मॉडल चुनने का विकल्प है. इसकी मदद से, ऐनिमेशन के अलग-अलग हिस्सों को चुना जा सकता है. इस इमेज में,
startConstraintSetको चुना गया है. इनके बीच ट्रांज़िशन चुनने के लिए, इनके बीच मौजूद ऐरो पर क्लिक करें.startend - सेक्शन – खास जानकारी के नीचे एक सेक्शन विंडो होती है. यह विंडो, चुनी गई खास जानकारी के आइटम के हिसाब से बदलती है. इस इमेज में,
startConstraintSetजानकारी को चुनने वाली विंडो में दिखाया गया है. - एट्रिब्यूट – एट्रिब्यूट पैनल में, चुने गए मौजूदा आइटम के एट्रिब्यूट दिखते हैं. साथ ही, इसकी मदद से, खास जानकारी या चुनने की विंडो से एट्रिब्यूट में बदलाव किया जा सकता है. इस इमेज में,
startConstraintSetके लिए एट्रिब्यूट दिखाए गए हैं.
तीसरा चरण: शुरू और खत्म होने की शर्तें तय करना
सभी ऐनिमेशन को शुरू और खत्म होने के हिसाब से तय किया जा सकता है. स्टार्ट में बताया जाता है कि ऐनिमेशन से पहले स्क्रीन कैसी दिखती है. वहीं, एंड में बताया जाता है कि ऐनिमेशन के बाद स्क्रीन कैसी दिखती है. MotionLayout यह तय करता है कि शुरुआती और आखिरी स्थिति के बीच ऐनिमेशन कैसे किया जाए.
MotionScene, शुरू और खत्म होने की स्थितियों को तय करने के लिए ConstraintSet टैग का इस्तेमाल करता है. ConstraintSet का मतलब है, कंस्ट्रेंट का एक सेट. इसे व्यू पर लागू किया जा सकता है. इसमें चौड़ाई, ऊंचाई, और ConstraintLayout की सीमाएं शामिल हैं. इसमें alpha जैसे कुछ एट्रिब्यूट भी शामिल हैं. इसमें व्यू की संख्या नहीं होती, बल्कि सिर्फ़ व्यू से जुड़ी पाबंदियां होती हैं.
ConstraintSet में बताई गई कोई भी शर्त, लेआउट फ़ाइल में बताई गई शर्तों को बदल देगी. अगर आपने लेआउट और MotionScene, दोनों में ही सीमाएं तय की हैं, तो सिर्फ़ MotionScene में तय की गई सीमाएं लागू होंगी.
इस चरण में, स्टार व्यू को स्क्रीन के सबसे ऊपर से शुरू होने और सबसे नीचे खत्म होने के लिए कंस्ट्रेंट किया जाएगा.
इस चरण को पूरा करने के लिए, मोशन एडिटर का इस्तेमाल किया जा सकता है. इसके अलावा, सीधे तौर पर activity_step1_scene.xml के टेक्स्ट में बदलाव करके भी इसे पूरा किया जा सकता है.
- खास जानकारी देने वाले पैनल में,
startConstraintSet चुनें

- चुने गए आइटम पैनल में जाकर,
red_starको चुनें. फ़िलहाल, इसमेंlayoutका सोर्स दिख रहा है. इसका मतलब है कि इसConstraintSetमें कोई पाबंदी नहीं है. सबसे ऊपर दाईं ओर मौजूद पेंसिल आइकॉन का इस्तेमाल करके, Constraint बनाएं

- पुष्टि करें कि खास जानकारी वाले पैनल में
startConstraintSetको चुनने पर,red_starमेंstartका सोर्स दिखता है. - एट्रिब्यूट पैनल में,
startConstraintSetमेंred_starको चुनें. इसके बाद, सबसे ऊपर एक कंस्ट्रेंट जोड़ें. इसके लिए, नीले रंग के + बटन पर क्लिक करें.

- इस कंस्ट्रेंट के लिए Motion Editor ने जो कोड जनरेट किया है उसे देखने के लिए,
xml/activity_step1_scene.xmlखोलें.
activity_step1_scene.xml
<!-- Constraints to apply at the start of the animation -->
<ConstraintSet android:id="@+id/start">
<Constraint
android:id="@+id/red_star"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
motion:layout_constraintStart_toStartOf="parent"
motion:layout_constraintTop_toTopOf="parent" />
</ConstraintSet>
ConstraintSet में id का @id/start है. साथ ही, इसमें MotionLayout के सभी व्यू पर लागू होने वाली सभी पाबंदियां बताई गई हैं. इस MotionLayout में सिर्फ़ एक व्यू है. इसलिए, इसमें सिर्फ़ एक Constraint की ज़रूरत है.
ConstraintSet के अंदर मौजूद Constraint, उस व्यू का आईडी तय करता है जिस पर यह पाबंदी लगा रहा है. @id/red_star को activity_step1.xml में तय किया गया है. यह ध्यान रखना ज़रूरी है कि Constraint टैग सिर्फ़ सीमाओं और लेआउट की जानकारी देते हैं. Constraint टैग को यह नहीं पता कि इसे ImageView पर लागू किया जा रहा है.
इस कंस्ट्रेंट में, red_star व्यू की ऊंचाई, चौड़ाई, और दो अन्य कंस्ट्रेंट के बारे में बताया गया है. इनकी मदद से, red_star व्यू को उसके पैरंट के टॉप स्टार्ट में कंस्ट्रेंट किया जा सकता है.
- खास जानकारी देने वाले पैनल में,
endConstraintSet चुनें.

endConstraintSetमेंred_starके लिएConstraintजोड़ने के लिए, पहले की तरह ही यह तरीका अपनाएं.- इस चरण को पूरा करने के लिए, मोशन एडिटर का इस्तेमाल करें. इसके लिए, नीले रंग के + बटन पर क्लिक करके,
bottomऔरendमें कोई कंस्ट्रेंट जोड़ें.

- एक्सएमएल में कोड ऐसा दिखता है:
activitiy_step1_scene.xml
<!-- Constraints to apply at the end of the animation -->
<ConstraintSet android:id="@+id/end">
<Constraint
android:id="@+id/red_star"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
motion:layout_constraintEnd_toEndOf="parent"
motion:layout_constraintBottom_toBottomOf="parent" />
</ConstraintSet>
@id/start की तरह, इस ConstraintSet में @id/red_star पर एक ही Constraint है. इस बार, इसे स्क्रीन के सबसे नीचे वाले हिस्से में सेट किया जाता है.
यह ज़रूरी नहीं है कि आप उन्हें @id/start और @id/end नाम दें. हालांकि, ऐसा करना आसान होता है.
चौथा चरण: ट्रांज़िशन तय करना
हर MotionScene में कम से कम एक ट्रांज़िशन भी शामिल होना चाहिए. ट्रांज़िशन, किसी ऐनिमेशन के हर हिस्से को तय करता है. यह ऐनिमेशन की शुरुआत से लेकर आखिर तक होता है.
ट्रांज़िशन के लिए, ट्रांज़िशन के शुरू और खत्म होने का ConstraintSet तय करना ज़रूरी है. ट्रांज़िशन से यह भी तय किया जा सकता है कि ऐनिमेशन में अन्य बदलाव कैसे किए जाएं. जैसे, ऐनिमेशन को कितनी देर तक चलाना है या व्यू को खींचकर ऐनिमेशन कैसे करना है.
- MotionScene फ़ाइल बनाते समय, Motion Editor ने डिफ़ॉल्ट रूप से हमारे लिए ट्रांज़िशन बनाया. जनरेट किया गया ट्रांज़िशन देखने के लिए,
activity_step1_scene.xmlखोलें.
activity_step1_scene.xml
<!-- A transition describes an animation via start and end state -->
<Transition
motion:constraintSetEnd="@+id/end"
motion:constraintSetStart="@id/start"
motion:duration="1000">
<KeyFrameSet>
</KeyFrameSet>
</Transition>
ऐनिमेशन बनाने के लिए, MotionLayout को इन सभी चीज़ों की ज़रूरत होती है. हर एट्रिब्यूट को देखने पर:
- ऐनिमेशन शुरू होने पर, व्यू पर
constraintSetStartलागू हो जाएगा. - ऐनिमेशन के आखिर में, व्यू पर
constraintSetEndलागू किया जाएगा. durationसे पता चलता है कि ऐनिमेशन को पूरा होने में कितना समय लगेगा. यह समय मिलीसेकंड में होता है.
इसके बाद, MotionLayout, शुरू और खत्म होने की सीमाओं के बीच का पाथ तय करेगा और उसे तय की गई अवधि के लिए ऐनिमेट करेगा.
पांचवां चरण: मोशन एडिटर में ऐनिमेशन की झलक देखना

ऐनिमेशन: मोशन एडिटर में ट्रांज़िशन की झलक दिखाने वाला वीडियो
- मोशन एडिटर खोलें. इसके बाद, खास जानकारी वाले पैनल में मौजूद
startऔरendके बीच मौजूद ऐरो पर क्लिक करके ट्रांज़िशन चुनें.

- ट्रांज़िशन चुनने पर, चुने गए आइटम पैनल में, वीडियो चलाने के कंट्रोल और स्क्रबर बार दिखता है. ऐनिमेशन की झलक देखने के लिए, चलाएं पर क्लिक करें या मौजूदा स्थिति को खींचें.

छठा चरण: क्लिक करने पर काम करने वाला हैंडलर जोड़ना
ऐनिमेशन शुरू करने के लिए, आपके पास कोई तरीका होना चाहिए. इसके लिए, MotionLayout को @id/red_star पर क्लिक इवेंट का जवाब देने के लिए सेट किया जा सकता है.
- मोशन एडिटर खोलें और ट्रांज़िशन चुनें. इसके लिए, खास जानकारी वाले पैनल में, शुरुआती और आखिरी फ़्रेम के बीच मौजूद ऐरो पर क्लिक करें.

- खास जानकारी वाले पैनल के टूलबार में,
क्लिक या स्वाइप हैंडलर बनाएं पर क्लिक करें . इससे एक हैंडलर जुड़ जाता है, जो ट्रांज़िशन शुरू करेगा. - पॉप-अप से Click Handler चुनें

- व्यू टू क्लिक को
red_starपर सेट करें.

- जोड़ें पर क्लिक करें. क्लिक हैंडलर को मोशन एडिटर में ट्रांज़िशन पर एक छोटे बिंदु के तौर पर दिखाया जाता है.

- खास जानकारी वाले पैनल में ट्रांज़िशन को चुनकर, एट्रिब्यूट पैनल में अभी-अभी जोड़े गए OnClick हैंडलर में
toggleकाclickActionएट्रिब्यूट जोड़ें.

- मोशन एडिटर से जनरेट किया गया कोड देखने के लिए,
activity_step1_scene.xmlखोलें
activity_step1_scene.xml
<!-- A transition describes an animation via start and end state -->
<Transition
motion:constraintSetStart="@+id/start"
motion:constraintSetEnd="@+id/end"
motion:duration="1000">
<!-- MotionLayout will handle clicks on @id/red_star to "toggle" the animation between the start and end -->
<OnClick
motion:targetId="@id/red_star"
motion:clickAction="toggle" />
</Transition>
Transition, MotionLayout को बताता है कि क्लिक इवेंट के जवाब में ऐनिमेशन को <OnClick> टैग का इस्तेमाल करके चलाया जाए. हर एट्रिब्यूट को देखने पर:
targetIdमें क्लिक की जानकारी देखी जा सकती है.toggleकाclickAction, क्लिक करने पर शुरू और खत्म होने की स्थिति के बीच स्विच करेगा.clickActionके अन्य विकल्प देखने के लिए, दस्तावेज़ देखें.
- कोड चलाएं. इसके बाद, पहला चरण पर क्लिक करें. इसके बाद, लाल तारे पर क्लिक करें और ऐनिमेशन देखें!
पांचवां चरण: ऐनिमेशन का इस्तेमाल करना
ऐप्लिकेशन चलाएं! स्टार पर क्लिक करने पर, आपको ऐनिमेशन चलता हुआ दिखना चाहिए.

मोशन सीन की पूरी हो चुकी फ़ाइल में एक Transition होता है, जो शुरू और खत्म होने वाले ConstraintSet की ओर इशारा करता है.
ऐनिमेशन की शुरुआत (@id/start) में, स्टार आइकॉन को स्क्रीन के सबसे ऊपर बाईं ओर रखा गया है. ऐनिमेशन (@id/end) के आखिर में, तारे के आइकॉन को स्क्रीन के सबसे नीचे वाले हिस्से पर रखा जाता है.
<?xml version="1.0" encoding="utf-8"?>
<!-- Describe the animation for activity_step1.xml -->
<MotionScene xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android">
<!-- A transition describes an animation via start and end state -->
<Transition
motion:constraintSetStart="@+id/start"
motion:constraintSetEnd="@+id/end"
motion:duration="1000">
<!-- MotionLayout will handle clicks on @id/star to "toggle" the animation between the start and end -->
<OnClick
motion:targetId="@id/red_star"
motion:clickAction="toggle" />
</Transition>
<!-- Constraints to apply at the end of the animation -->
<ConstraintSet android:id="@+id/start">
<Constraint
android:id="@+id/red_star"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
motion:layout_constraintStart_toStartOf="parent"
motion:layout_constraintTop_toTopOf="parent" />
</ConstraintSet>
<!-- Constraints to apply at the end of the animation -->
<ConstraintSet android:id="@+id/end">
<Constraint
android:id="@+id/red_star"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
motion:layout_constraintEnd_toEndOf="parent"
motion:layout_constraintBottom_toBottomOf="parent" />
</ConstraintSet>
</MotionScene>
4. ड्रैग इवेंट के आधार पर ऐनिमेशन
इस चरण में, आपको एक ऐसा ऐनिमेशन बनाना होगा जो उपयोगकर्ता के ड्रैग इवेंट (जब उपयोगकर्ता स्क्रीन पर स्वाइप करता है) पर प्रतिक्रिया दे, ताकि ऐनिमेशन चल सके. MotionLayout इसमें व्यू को मूव करने के लिए, टच इवेंट को ट्रैक करने की सुविधा होती है. साथ ही, फ़िज़िक्स पर आधारित फ़्लिंग जेस्चर की सुविधा होती है, ताकि मोशन को फ़्लूड बनाया जा सके.
पहला चरण: ओरिजनल कोड की जांच करना
- शुरू करने के लिए, लेआउट फ़ाइल
activity_step2.xmlखोलें. इसमें पहले से मौजूदMotionLayoutहै. कोड देखें.
activity_step2.xml
<!-- initial code -->
<androidx.constraintlayout.motion.widget.MotionLayout
...
motion:layoutDescription="@xml/step2" >
<ImageView
android:id="@+id/left_star"
...
/>
<ImageView
android:id="@+id/right_star"
...
/>
<ImageView
android:id="@+id/red_star"
...
/>
<TextView
android:id="@+id/credits"
...
motion:layout_constraintTop_toTopOf="parent"
motion:layout_constraintEnd_toEndOf="parent"/>
</androidx.constraintlayout.motion.widget.MotionLayout>
इस लेआउट में, ऐनिमेशन के सभी व्यू तय किए जाते हैं. लेआउट में तीन स्टार आइकॉन को सीमित नहीं किया गया है, क्योंकि मोशन सीन में इन्हें ऐनिमेट किया जाएगा.
क्रेडिट TextView पर पाबंदियां लागू होती हैं, क्योंकि यह पूरे ऐनिमेशन के दौरान एक ही जगह पर रहता है और किसी भी एट्रिब्यूट में बदलाव नहीं करता है.
दूसरा चरण: सीन को ऐनिमेट करना
पिछले ऐनिमेशन की तरह ही, इस ऐनिमेशन को भी शुरू और खत्म होने के ConstraintSet, और Transition के हिसाब से तय किया जाएगा.
शुरुआत के ConstraintSet को तय करें
- ऐनिमेशन तय करने के लिए, मोशन सीन
xml/step2.xmlखोलें. - शुरुआती कंस्ट्रेंट
startके लिए कंस्ट्रेंट जोड़ें. शुरुआत में, तीनों स्टार स्क्रीन पर सबसे नीचे बीच में होते हैं. दाईं और बाईं ओर मौजूद स्टार कीalphaवैल्यू0.0है. इसका मतलब है कि ये पूरी तरह से पारदर्शी हैं और छिपे हुए हैं.
step2.xml
<!-- TODO apply starting constraints -->
<!-- Constraints to apply at the start of the animation -->
<ConstraintSet android:id="@+id/start">
<Constraint
android:id="@+id/red_star"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
motion:layout_constraintStart_toStartOf="parent"
motion:layout_constraintEnd_toEndOf="parent"
motion:layout_constraintBottom_toBottomOf="parent" />
<Constraint
android:id="@+id/left_star"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:alpha="0.0"
motion:layout_constraintStart_toStartOf="parent"
motion:layout_constraintEnd_toEndOf="parent"
motion:layout_constraintBottom_toBottomOf="parent" />
<Constraint
android:id="@+id/right_star"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:alpha="0.0"
motion:layout_constraintStart_toStartOf="parent"
motion:layout_constraintEnd_toEndOf="parent"
motion:layout_constraintBottom_toBottomOf="parent" />
</ConstraintSet>
इस ConstraintSet में, हर स्टार के लिए एक Constraint तय किया जाता है. हर कंस्ट्रेंट को MotionLayout, ऐनिमेशन की शुरुआत में लागू करेगा.
हर स्टार व्यू को स्क्रीन पर सबसे नीचे बीच में रखा गया है. इसके लिए, स्टार्ट, एंड, और बॉटम कंस्ट्रेंट का इस्तेमाल किया गया है. दोनों स्टार @id/left_star और @id/right_star में एक अतिरिक्त ऐल्फ़ा वैल्यू होती है, जो उन्हें अदृश्य बना देती है. यह वैल्यू, ऐनिमेशन की शुरुआत में लागू होगी.
start और end कंस्ट्रेंट सेट, ऐनिमेशन की शुरुआत और खत्म होने की स्थिति तय करते हैं. स्टार्ट पर कंस्ट्रेंट, जैसे कि motion:layout_constraintStart_toStartOf, किसी व्यू के स्टार्ट को दूसरे व्यू के स्टार्ट पर कंस्ट्रेंट करेगा. शुरुआत में यह मुश्किल लग सकता है, क्योंकि start नाम का इस्तेमाल और दोनों के लिए किया जाता है. साथ ही, दोनों का इस्तेमाल शर्तों के संदर्भ में किया जाता है. इनके बीच के अंतर को समझने के लिए, start में मौजूद layout_constraintStart का मतलब व्यू की "शुरुआत" से है. बाईं से दाईं ओर लिखी जाने वाली भाषा में यह बाईं ओर होता है और दाईं से बाईं ओर लिखी जाने वाली भाषा में यह दाईं ओर होता है. start कॉन्स्ट्रेंट सेट, ऐनिमेशन की शुरुआत को दिखाता है.
आखिरी ConstraintSet को तय करना
@id/creditsके नीचे तीनों स्टार को एक साथ रखने के लिए, चेन का इस्तेमाल करने के लिए एंड कंस्ट्रेंट तय करें. इसके अलावा, यह बाईं और दाईं ओर मौजूद स्टार केalphaकी आखिरी वैल्यू को1.0पर सेट कर देगा.
step2.xml
<!-- TODO apply ending constraints -->
<!-- Constraints to apply at the end of the animation -->
<ConstraintSet android:id="@+id/end">
<Constraint
android:id="@+id/left_star"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:alpha="1.0"
motion:layout_constraintHorizontal_chainStyle="packed"
motion:layout_constraintStart_toStartOf="parent"
motion:layout_constraintEnd_toStartOf="@id/red_star"
motion:layout_constraintTop_toBottomOf="@id/credits" />
<Constraint
android:id="@+id/red_star"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
motion:layout_constraintStart_toEndOf="@id/left_star"
motion:layout_constraintEnd_toStartOf="@id/right_star"
motion:layout_constraintTop_toBottomOf="@id/credits" />
<Constraint
android:id="@+id/right_star"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:alpha="1.0"
motion:layout_constraintStart_toEndOf="@id/red_star"
motion:layout_constraintEnd_toEndOf="parent"
motion:layout_constraintTop_toBottomOf="@id/credits" />
</ConstraintSet>
आखिरी नतीजा यह है कि ऐनिमेशन के दौरान व्यू, बीच से बाहर की ओर और ऊपर की ओर फैल जाएंगे.
इसके अलावा, ConstraintSets में @id/right_start और @id/left_star, दोनों पर alpha प्रॉपर्टी सेट की गई है. इसलिए, ऐनिमेशन के आगे बढ़ने पर दोनों व्यू फ़ेड इन हो जाएंगे.
उपयोगकर्ता के स्वाइप करने के आधार पर ऐनिमेशन
MotionLayout, उपयोगकर्ता के ड्रैग इवेंट या स्वाइप को ट्रैक कर सकता है, ताकि फ़िज़िक्स पर आधारित "फ़्लिंग" ऐनिमेशन बनाया जा सके. इसका मतलब है कि अगर उपयोगकर्ता उन्हें फ़्लिंग करता है, तो वे दिखते रहेंगे. साथ ही, किसी सतह पर लुढ़कने के दौरान, किसी चीज़ की रफ़्तार कम होने की तरह ही, इनकी रफ़्तार भी कम हो जाएगी. Transition में OnSwipe टैग का इस्तेमाल करके, इस तरह का ऐनिमेशन जोड़ा जा सकता है.
OnSwipeटैग जोड़ने के लिए, TODO को<OnSwipe motion:touchAnchorId="@id/red_star" />से बदलें.
step2.xml
<!-- TODO add OnSwipe tag -->
<!-- A transition describes an animation via start and end state -->
<Transition
motion:constraintSetStart="@+id/start"
motion:constraintSetEnd="@+id/end">
<!-- MotionLayout will track swipes relative to this view -->
<OnSwipe motion:touchAnchorId="@id/red_star" />
</Transition>
OnSwipe में कुछ एट्रिब्यूट होते हैं. इनमें सबसे अहम एट्रिब्यूट touchAnchorId होता है.
touchAnchorId, ट्रैक किया गया व्यू है. यह छूने पर मूव करता है.MotionLayoutइस व्यू को उस उंगली से उतनी ही दूरी पर रखेगा जिससे स्वाइप किया जा रहा है.touchAnchorSideसे यह तय होता है कि व्यू के किस हिस्से को ट्रैक किया जाना चाहिए. यह उन व्यू के लिए ज़रूरी है जिनका साइज़ बदलता है, जो मुश्किल पाथ फ़ॉलो करते हैं या जिनका एक हिस्सा दूसरे हिस्से के मुकाबले ज़्यादा तेज़ी से मूव करता है.dragDirectionसे यह तय होता है कि इस ऐनिमेशन के लिए कौनसी दिशा मायने रखती है (ऊपर, नीचे, बाएं या दाएं).
जब MotionLayout ड्रैग इवेंट के लिए सुनता है, तो लिसनर को MotionLayout व्यू पर रजिस्टर किया जाएगा, न कि touchAnchorId के ज़रिए तय किए गए व्यू पर. जब कोई उपयोगकर्ता स्क्रीन पर कहीं भी जेस्चर शुरू करता है, तो MotionLayout, उसकी उंगली और touchAnchorId व्यू के touchAnchorSide के बीच की दूरी को स्थिर रखता है. अगर वे ऐंकर साइड से 100 डीपी दूर टच करते हैं, तो उदाहरण के लिए, MotionLayout पूरे ऐनिमेशन के दौरान उस साइड को उनकी उंगली से 100 डीपी दूर रखेगा.
इसे आज़माएं
- ऐप्लिकेशन को फिर से चलाएं और दूसरे चरण वाली स्क्रीन खोलें. आपको ऐनिमेशन दिखेगा.
- ऐनिमेशन के बीच में अपनी उंगली को "फ़्लिंग" करके या छोड़कर देखें कि
MotionLayout, फ़्लूड फ़िज़िक्स पर आधारित ऐनिमेशन कैसे दिखाता है!

MotionLayout की सुविधाओं का इस्तेमाल करके, अलग-अलग डिज़ाइन के बीच ऐनिमेशन बनाया जा सकता है. साथ ही, ConstraintLayout की मदद से शानदार इफ़ेक्ट बनाए जा सकते हैं.
इस ऐनिमेशन में, तीनों व्यू को स्क्रीन पर सबसे नीचे मौजूद उनके पैरंट के हिसाब से पोज़िशन किया गया है. आखिर में, तीनों व्यू को चेन में @id/credits के हिसाब से सेट किया जाता है.
इन अलग-अलग लेआउट के बावजूद, MotionLayout शुरू और खत्म होने के बीच एक फ़्लूड ऐनिमेशन बनाएगा.
5. पाथ में बदलाव करना
इस चरण में, आपको एक ऐसा ऐनिमेशन बनाना होगा जो ऐनिमेशन के दौरान एक मुश्किल पाथ को फ़ॉलो करता है. साथ ही, मोशन के दौरान क्रेडिट को ऐनिमेट करता है. MotionLayout का इस्तेमाल करके, किसी व्यू के शुरू होने और खत्म होने के बीच के पाथ में बदलाव किया जा सकता है.KeyPosition
पहला चरण: मौजूदा कोड एक्सप्लोर करना
- मौजूदा लेआउट और मोशन सीन देखने के लिए,
layout/activity_step3.xmlऔरxml/step3.xmlखोलें.ImageViewऔरTextViewमें, चंद्रमा और क्रेडिट टेक्स्ट दिखाया गया है. - मोशन सीन फ़ाइल (
xml/step3.xml) खोलें. आपको दिखेगा कि@id/startसे@id/endतक काTransitionतय किया गया है. इस ऐनिमेशन में, चंद्रमा की इमेज को स्क्रीन के नीचे बाईं ओर से नीचे दाईं ओर ले जाया जाता है. इसके लिए, दोConstraintSetsका इस्तेमाल किया जाता है. चांद के आगे बढ़ने पर, क्रेडिट टेक्स्टalpha="0.0"सेalpha="1.0"तक फ़ेड इन होता है. - अब ऐप्लिकेशन चलाएं और तीसरा चरण चुनें. आपको दिखेगा कि चांद पर क्लिक करने पर, वह शुरू से आखिर तक एक सीधी लाइन में चलता है.
दूसरा चरण: पाथ डीबग करने की सुविधा चालू करना
चाँद की गति में आर्क जोड़ने से पहले, MotionLayout में पाथ डीबग करने की सुविधा चालू करना मददगार होता है.
MotionLayout की मदद से मुश्किल ऐनिमेशन बनाने के लिए, हर व्यू का ऐनिमेशन पाथ बनाया जा सकता है. यह आपके ऐनिमेशन को विज़ुअलाइज़ करने और मोशन की छोटी-छोटी बारीकियों को बेहतर बनाने में मददगार होता है.
- डीबगिंग पाथ चालू करने के लिए,
layout/activity_step3.xmlखोलें औरMotionLayoutटैग मेंmotion:motionDebug="SHOW_PATH"जोड़ें.
activity_step3.xml
<!-- Add motion:motionDebug="SHOW_PATH" -->
<androidx.constraintlayout.motion.widget.MotionLayout
...
motion:motionDebug="SHOW_PATH" >
पाथ डीबगिंग चालू करने के बाद, ऐप्लिकेशन को फिर से चलाने पर आपको सभी व्यू के पाथ, डॉटेड लाइन के साथ दिखेंगे.

- सर्कल, किसी एक व्यू की शुरुआती या आखिरी पोज़िशन को दिखाते हैं.
- लाइनें, एक व्यू के पाथ को दिखाती हैं.
- डायमंड, एक
KeyPositionको दिखाते हैं जो पाथ में बदलाव करता है.
उदाहरण के लिए, इस ऐनिमेशन में बीच वाला सर्कल, क्रेडिट टेक्स्ट की जगह है.
तीसरा चरण: पाथ में बदलाव करना
MotionLayout में मौजूद सभी ऐनिमेशन, शुरू होने और खत्म होने वाले ConstraintSet से तय होते हैं. इससे यह तय होता है कि ऐनिमेशन शुरू होने से पहले और खत्म होने के बाद स्क्रीन कैसी दिखेगी. डिफ़ॉल्ट रूप से, MotionLayout हर उस व्यू के शुरुआती और आखिरी पोज़िशन के बीच एक लीनियर पाथ (सीधी लाइन) प्लॉट करता है जिसकी पोज़िशन बदलती है.
इस उदाहरण में, चंद्रमा के आर्क जैसे मुश्किल पाथ बनाने के लिए, MotionLayout KeyPosition का इस्तेमाल करता है. इससे, व्यू के शुरुआती और आखिरी पॉइंट के बीच के पाथ में बदलाव किया जा सकता है.
xml/step3.xmlखोलें और सीन मेंKeyPositionजोड़ें.KeyPositionटैग कोTransitionटैग के अंदर रखा जाता है.

step3.xml
<!-- TODO: Add KeyFrameSet and KeyPosition -->
<KeyFrameSet>
<KeyPosition
motion:framePosition="50"
motion:motionTarget="@id/moon"
motion:keyPositionType="parentRelative"
motion:percentY="0.5"
/>
</KeyFrameSet>
KeyFrameSet, Transition का चाइल्ड होता है. यह KeyFrames का एक सेट होता है. जैसे, KeyPosition. इसे ट्रांज़िशन के दौरान लागू किया जाना चाहिए.
MotionLayout, चंद्रमा के शुरू होने और खत्म होने के बीच के रास्ते का हिसाब लगा रहा है. इसलिए, यह KeyFrameSet में दिए गए KeyPosition के आधार पर रास्ते में बदलाव करता है. ऐप्लिकेशन को फिर से चलाकर देखा जा सकता है कि इससे पाथ में क्या बदलाव होता है.
KeyPosition में कई एट्रिब्यूट होते हैं. इनसे पता चलता है कि यह पाथ में कैसे बदलाव करता है. इनमें से सबसे ज़रूरी ये हैं:
framePosition, 0 और 100 के बीच की कोई संख्या है. इससे यह तय होता है कि ऐनिमेशन में यहKeyPositionकब लागू होना चाहिए. इसमें 1 का मतलब है कि ऐनिमेशन के 1% पूरे होने पर और 99 का मतलब है कि ऐनिमेशन के 99% पूरे होने पर. इसलिए, अगर वैल्यू 50 है, तो इसे बीच में लागू करें.motionTargetवह व्यू है जिसके लिए यहKeyPositionपाथ में बदलाव करता है.keyPositionTypeसे पता चलता है किKeyPositionपाथ में कैसे बदलाव करता है. यहparentRelative,pathRelativeयाdeltaRelativeहो सकता है. इसके बारे में अगले चरण में बताया गया है.percentX | percentYसे पता चलता है किframePositionपर पाथ में कितना बदलाव करना है. इसकी वैल्यू 0.0 और 1.0 के बीच होती है. हालांकि, इसमें नेगेटिव वैल्यू और 1 से ज़्यादा वैल्यू भी इस्तेमाल की जा सकती हैं.
इसे इस तरह से समझा जा सकता है: "framePosition पर motionTarget के पाथ में बदलाव करो percentX या percentY कोऑर्डिनेट के हिसाब से keyPositionTypeसे motionTarget को percentX या percentY से keyPositionType तक ले जाकर."
डिफ़ॉल्ट रूप से, पाथ में बदलाव करने पर बने किसी भी कोने को MotionLayout गोल कर देगा. अभी-अभी बनाए गए एनिमेशन को देखने पर पता चलता है कि चंद्रमा, मुड़ने वाली जगह पर घुमावदार रास्ते पर चलता है. ज़्यादातर ऐनिमेशन के लिए, आपको यही चाहिए होता है. अगर ऐसा नहीं है, तो इसे पसंद के मुताबिक बनाने के लिए, curveFit एट्रिब्यूट का इस्तेमाल करें.
इसे आज़माएं
ऐप्लिकेशन को फिर से चलाने पर, आपको इस चरण के लिए ऐनिमेशन दिखेगा.

चांद एक आर्क को फ़ॉलो करता है, क्योंकि यह Transition में बताए गए KeyPosition से होकर गुज़रता है.
<KeyPosition
motion:framePosition="50"
motion:motionTarget="@id/moon"
motion:keyPositionType="parentRelative"
motion:percentY="0.5"
/>
इस KeyPosition को इस तरह पढ़ा जा सकता है: "framePosition 50 (ऐनिमेशन के बीच में) motionTarget @id/moon के पाथ में बदलाव करें. इसके लिए, इसे 50% Y (स्क्रीन के बीच में) parentRelative (पूरे MotionLayout) से तय किए गए कोऑर्डिनेट के हिसाब से ले जाएं."
इसलिए, ऐनिमेशन के बीच में, चंद्रमा को स्क्रीन पर 50% नीचे की ओर KeyPosition से गुज़रना होगा. इस KeyPosition से X मोशन में कोई बदलाव नहीं होता. इसलिए, चांद अब भी बाईं से दाईं ओर जाएगा. MotionLayout, शुरुआती और आखिरी स्थिति के बीच ट्रांज़िशन करते समय, इस KeyPosition से होकर गुज़रने वाला एक आसान पाथ तय करेगा.
ध्यान से देखने पर पता चलता है कि क्रेडिट टेक्स्ट, चंद्रमा की पोज़िशन के हिसाब से तय किया गया है. यह वर्टिकल तौर पर क्यों नहीं घूम रहा है?

<Constraint
android:id="@id/credits"
...
motion:layout_constraintBottom_toBottomOf="@id/moon"
motion:layout_constraintTop_toTopOf="@id/moon"
/>
इससे पता चलता है कि चांद के पाथ में बदलाव करने पर भी, चांद की शुरुआती और आखिरी पोज़िशन में कोई बदलाव नहीं होता. KeyPosition, शुरुआती या आखिरी पोज़िशन में बदलाव नहीं करता. इसलिए, क्रेडिट टेक्स्ट को चांद की आखिरी पोज़िशन तक सीमित रखा जाता है.
अगर आपको क्रेडिट को चांद के साथ मूव करना है, तो क्रेडिट में KeyPosition जोड़ें या @id/credits पर स्टार्ट कॉन्स्ट्रेंट में बदलाव करें.
अगले सेक्शन में, आपको MotionLayout में मौजूद अलग-अलग तरह के keyPositionType के बारे में जानकारी मिलेगी.
6. keyPositionType को समझना
पिछले चरण में, आपने स्क्रीन के 50% हिस्से में पाथ को ऑफ़सेट करने के लिए, keyPosition टाइप के parentRelative का इस्तेमाल किया था. keyPositionType एट्रिब्यूट से यह तय होता है कि MotionLayout, percentX या percentY के हिसाब से पाथ में कैसे बदलाव करेगा.
<KeyFrameSet>
<KeyPosition
motion:framePosition="50"
motion:motionTarget="@id/moon"
motion:keyPositionType="parentRelative"
motion:percentY="0.5"
/>
</KeyFrameSet>
keyPosition तीन तरह के हो सकते हैं: parentRelative, pathRelative, और deltaRelative. टाइप तय करने से, उस कोऑर्डिनेट सिस्टम में बदलाव होगा जिससे percentX और percentY की गिनती की जाती है.
निर्देशांक प्रणाली क्या होती है?
निर्देशांक प्रणाली की मदद से, किसी जगह पर मौजूद पॉइंट के बारे में जानकारी दी जा सकती है. ये स्क्रीन पर किसी जगह के बारे में बताने के लिए भी काम आते हैं.
MotionLayout कोऑर्डिनेट सिस्टम, कार्टेशियन कोऑर्डिनेट सिस्टम होता है. इसका मतलब है कि इनमें X और Y ऐक्सिस होते हैं, जिन्हें दो लंबवत रेखाओं से तय किया जाता है. इनके बीच मुख्य अंतर यह है कि स्क्रीन पर X ऐक्सिस कहां जाता है. Y ऐक्सिस हमेशा X ऐक्सिस के लंबवत होता है.
MotionLayout में मौजूद सभी कोऑर्डिनेट सिस्टम, X और Y, दोनों ऐक्सिस पर 0.0 और 1.0 के बीच की वैल्यू का इस्तेमाल करते हैं. इनमें नेगेटिव वैल्यू और 1.0 से बड़ी वैल्यू इस्तेमाल की जा सकती हैं. इसलिए, उदाहरण के लिए, percentX की वैल्यू -2.0 का मतलब होगा कि X ऐक्सिस की विपरीत दिशा में दो बार जाएं.
अगर आपको यह सब कुछ बीजगणित की क्लास जैसा लग रहा है, तो यहां दी गई तस्वीरें देखें!
parentRelative coordinates

keyPositionType का parentRelative, स्क्रीन के जैसा ही कोऑर्डिनेट सिस्टम इस्तेमाल करता है. यह पूरे MotionLayout के सबसे ऊपर बाईं ओर (0, 0) और सबसे नीचे दाईं ओर (1, 1) को तय करता है.
जब भी आपको ऐसा ऐनिमेशन बनाना हो जो पूरे MotionLayout में घूमता हो, तब parentRelative का इस्तेमाल किया जा सकता है. जैसे, इस उदाहरण में चंद्रमा का आर्क.
हालांकि, अगर आपको मोशन के हिसाब से किसी पाथ में बदलाव करना है, जैसे कि उसे थोड़ा घुमाना है, तो अन्य दो कोऑर्डिनेट सिस्टम बेहतर विकल्प हैं.
deltaRelative कोऑर्डिनेट

डेल्टा, गणित में बदलाव के लिए इस्तेमाल किया जाने वाला शब्द है. इसलिए, deltaRelative का मतलब "बदलाव से जुड़ा" है. deltaRelative निर्देशांकों में, (0,0) व्यू की शुरुआती पोज़िशन है और (1,1) आखिरी पोज़िशन है. X और Y ऐक्सिस, स्क्रीन के साथ अलाइन किए जाते हैं.
स्क्रीन पर X ऐक्सिस हमेशा हॉरिज़ॉन्टल होता है और Y ऐक्सिस हमेशा वर्टिकल होता है. parentRelative की तुलना में, मुख्य अंतर यह है कि कोऑर्डिनेट सिर्फ़ स्क्रीन के उस हिस्से के बारे में बताते हैं जिसमें व्यू मूव करेगा.
deltaRelative एक बेहतरीन कोऑर्डिनेट सिस्टम है. इसकी मदद से, हॉरिज़ॉन्टल या वर्टिकल मोशन को अलग-अलग कंट्रोल किया जा सकता है. उदाहरण के लिए, ऐसा ऐनिमेशन बनाया जा सकता है जिसमें वर्टिकल (Y) मूवमेंट 50% पर पूरा हो जाता है और हॉरिज़ॉन्टल (X) मूवमेंट जारी रहता है.
pathRelative coordinates

MotionLayout में मौजूद आखिरी कोऑर्डिनेट सिस्टम pathRelative है. यह अन्य दो से काफ़ी अलग है, क्योंकि X ऐक्सिस, मोशन पाथ को शुरू से आखिर तक फ़ॉलो करता है. इसलिए, (0,0) शुरुआती पोज़िशन है और (1,0) आखिरी पोज़िशन है.
आपको इसकी ज़रूरत क्यों है? पहली नज़र में यह काफ़ी हैरान करने वाला लगता है. ऐसा इसलिए, क्योंकि यह कोऑर्डिनेट सिस्टम, स्क्रीन के कोऑर्डिनेट सिस्टम के साथ अलाइन भी नहीं है.
हमें पता चला कि pathRelative कुछ कामों के लिए बहुत मददगार है.
- ऐनिमेशन के किसी हिस्से के दौरान व्यू की स्पीड बढ़ाना, कम करना या उसे रोकना. X डाइमेंशन हमेशा व्यू के पाथ से मैच करेगा. इसलिए,
pathRelativeKeyPositionका इस्तेमाल करके यह बदला जा सकता है कि उस पाथ में किसी खास पॉइंट पर कौनसेframePositionपर पहुंचा जाए. इसलिए,framePosition="50"परframePosition="50"के साथpercentX="0.1"होने पर, ऐनिमेशन को मोशन के पहले 10% हिस्से को पूरा करने में 50% समय लगेगा.KeyPosition - किसी पाथ में हल्का सा आर्क जोड़ना. Y डाइमेंशन हमेशा मोशन के लंबवत होता है. इसलिए, Y में बदलाव करने से, मोशन के हिसाब से पाथ में बदलाव होगा.
deltaRelativeके साथ दूसरा डाइमेंशन जोड़ने पर, यह काम नहीं करेगा. पूरी तरह से हॉरिज़ॉन्टल और वर्टिकल मोशन के लिए,deltaRelativeसिर्फ़ एक काम का डाइमेंशन बनाएगा. हालांकि,pathRelativeहमेशा इस्तेमाल किए जा सकने वाले X और Y कोऑर्डिनेट बनाता है.
अगले चरण में, एक से ज़्यादा KeyPosition का इस्तेमाल करके, ज़्यादा जटिल पाथ बनाने का तरीका जानें.
7. जटिल पाथ बनाना
पिछले चरण में बनाए गए ऐनिमेशन को देखने पर पता चलता है कि इससे एक स्मूद कर्व बनता है. हालांकि, इसका आकार "चांद जैसा" हो सकता है.
एक से ज़्यादा KeyPosition एलिमेंट वाले पाथ में बदलाव करना
MotionLayout, किसी पाथ में और बदलाव कर सकता है. इसके लिए, वह ज़रूरत के मुताबिक कई KeyPosition तय कर सकता है, ताकि कोई भी मोशन मिल सके. इस ऐनिमेशन के लिए, आपको एक आर्क बनाना होगा. हालांकि, अगर आपको चंद्रमा को स्क्रीन के बीच में ऊपर और नीचे कूदते हुए दिखाना है, तो ऐसा किया जा सकता है.
xml/step4.xmlखोलें. आपको दिखेगा कि इस वीडियो पर उतने ही व्यू हैं जितने पहले थे. साथ ही, इसमें वहीKeyFrameजोड़ा गया है जो आपने पिछले चरण में जोड़ा था.- कर्व के ऊपरी हिस्से को गोल करने के लिए,
@id/moonके पाथ में दो औरKeyPositionsजोड़ें. एक को सबसे ऊपर पहुंचने से ठीक पहले और दूसरे को उसके बाद जोड़ें.

step4.xml
<!-- TODO: Add two more KeyPositions to the KeyFrameSet here -->
<KeyPosition
motion:framePosition="25"
motion:motionTarget="@id/moon"
motion:keyPositionType="parentRelative"
motion:percentY="0.6"
/>
<KeyPosition
motion:framePosition="75"
motion:motionTarget="@id/moon"
motion:keyPositionType="parentRelative"
motion:percentY="0.6"
/>
ये KeyPositions, ऐनिमेशन के 25% और 75% हिस्से पर लागू होंगे. साथ ही, @id/moon को स्क्रीन के सबसे ऊपर से 60% हिस्से तक ले जाएंगे. मौजूदा 50% KeyPosition के साथ मिलकर, यह चांद के लिए एक स्मूद आर्क बनाता है.
MotionLayout में, आपको जिस तरह का मोशन पाथ चाहिए उसके लिए, उतने KeyPositions जोड़े जा सकते हैं. MotionLayout, तय किए गए framePosition पर हर KeyPosition को लागू करेगा. साथ ही, यह पता लगाएगा कि सभी KeyPositions से होकर गुज़रने वाली स्मूद मोशन कैसे बनाई जाए.
इसे आज़माएं
- ऐप्लिकेशन को फिर से चलाएं. ऐनिमेशन को काम करते हुए देखने के लिए, चौथे चरण पर जाएं. चांद पर क्लिक करने पर, वह शुरू से लेकर आखिर तक के रास्ते पर चलता है. इस दौरान, वह हर उस
KeyPositionसे होकर गुज़रता है जिसेKeyFrameSetमें तय किया गया था.
अपने हिसाब से एक्सप्लोर करें
अन्य तरह के KeyFrame इस्तेमाल करने से पहले, KeyFrameSet में कुछ और KeyPositions जोड़कर देखें कि सिर्फ़ KeyPosition का इस्तेमाल करके किस तरह के इफ़ेक्ट बनाए जा सकते हैं.
यहां एक उदाहरण दिया गया है, जिसमें यह दिखाया गया है कि ऐनिमेशन के दौरान आगे-पीछे होने वाला मुश्किल पाथ कैसे बनाया जाता है.

step4.xml
<!-- Complex paths example: Dancing moon -->
<KeyFrameSet>
<KeyPosition
motion:framePosition="25"
motion:motionTarget="@id/moon"
motion:keyPositionType="parentRelative"
motion:percentY="0.6"
motion:percentX="0.1"
/>
<KeyPosition
motion:framePosition="50"
motion:motionTarget="@id/moon"
motion:keyPositionType="parentRelative"
motion:percentY="0.5"
motion:percentX="0.3"
/>
<KeyPosition
motion:framePosition="75"
motion:motionTarget="@id/moon"
motion:keyPositionType="parentRelative"
motion:percentY="0.6"
motion:percentX="0.1"
/>
</KeyFrameSet>
KeyPosition के बारे में जानने के बाद, अगले चरण में आपको अन्य तरह के KeyFrames के बारे में बताया जाएगा.
8. मोशन के दौरान एट्रिब्यूट बदलना
डाइनैमिक ऐनिमेशन बनाने का मतलब अक्सर यह होता है कि ऐनिमेशन के आगे बढ़ने पर, व्यू के size, rotation या alpha को बदला जाए. MotionLayout, KeyAttribute का इस्तेमाल करके किसी भी व्यू पर कई एट्रिब्यूट को ऐनिमेट करने की सुविधा देता है.
इस चरण में, चांद को छोटा-बड़ा करने और घुमाने के लिए KeyAttribute का इस्तेमाल किया जाएगा. इसके अलावा, टेक्स्ट को तब तक छिपाने के लिए KeyAttribute का इस्तेमाल किया जाएगा, जब तक चंद्रमा अपनी यात्रा पूरी न कर ले.
पहला चरण: KeyAttribute की मदद से इमेज का साइज़ बदलना और उसे घुमाना
xml/step5.xmlखोलें. इसमें वही ऐनिमेशन है जिसे आपने पिछले चरण में बनाया था. इस स्क्रीन पर, बैकग्राउंड के तौर पर अंतरिक्ष की किसी दूसरी तस्वीर का इस्तेमाल किया गया है.- चांद को बड़ा करने और घुमाने के लिए,
keyFrame="50"औरkeyFrame="100"पर मौजूदKeyFrameSetमें दोKeyAttributeटैग जोड़ें

step5.xml
<!-- TODO: Add KeyAttributes to rotate and resize @id/moon -->
<KeyAttribute
motion:framePosition="50"
motion:motionTarget="@id/moon"
android:scaleY="2.0"
android:scaleX="2.0"
android:rotation="-360"
/>
<KeyAttribute
motion:framePosition="100"
motion:motionTarget="@id/moon"
android:rotation="-720"
/>
ये KeyAttributes, ऐनिमेशन के 50% और 100% पर लागू होते हैं. 50% पर पहला KeyAttribute, आर्क के सबसे ऊपर होगा. इससे व्यू का साइज़ दोगुना हो जाएगा. साथ ही, यह -360 डिग्री (या एक पूरा सर्कल) घूम जाएगा. दूसरा KeyAttribute, दूसरे रोटेशन को -720 डिग्री (दो पूरे सर्कल) पर खत्म करेगा. साथ ही, साइज़ को वापस सामान्य पर ले जाएगा, क्योंकि scaleX और scaleY की वैल्यू डिफ़ॉल्ट रूप से 1.0 पर सेट होती हैं.
KeyPosition की तरह, KeyAttribute भी framePosition और motionTarget का इस्तेमाल करता है. इससे यह तय किया जाता है कि KeyFrame को कब लागू करना है और किस व्यू में बदलाव करना है. MotionLayout, फ़्लूइड ऐनिमेशन बनाने के लिए KeyPositions के बीच इंटरपोलेट करेगा.
KeyAttributes में ऐसे एट्रिब्यूट काम करते हैं जिन्हें सभी व्यू पर लागू किया जा सकता है. इनसे, visibility, alpha या elevation जैसे बुनियादी एट्रिब्यूट की वैल्यू बदली जा सकती है. यहाँ की तरह, रोटेशन को भी बदला जा सकता है. rotateX और rotateY की मदद से, तीन डाइमेंशन में घुमाएँ. scaleX और scaleY की मदद से, साइज़ को स्केल करें या X, Y या Z में व्यू की पोज़िशन बदलें.
दूसरा चरण: क्रेडिट दिखने में देरी करना
इस चरण का एक मकसद, ऐनिमेशन को अपडेट करना है, ताकि क्रेडिट टेक्स्ट तब तक न दिखे, जब तक ऐनिमेशन ज़्यादातर पूरा न हो जाए.
- क्रेडिट दिखने में देरी करने के लिए, एक और
KeyAttributeतय करें. इससे यह पक्का होगा किkeyPosition="85"तकalphaकी वैल्यू 0 रहेगी.MotionLayoutअब भी 0 से 100 ऐल्फ़ा में आसानी से बदल जाएगा. हालांकि, यह बदलाव ऐनिमेशन के आखिरी 15% हिस्से में होगा.
step5.xml
<!-- TODO: Add KeyAttribute to delay the appearance of @id/credits -->
<KeyAttribute
motion:framePosition="85"
motion:motionTarget="@id/credits"
android:alpha="0.0"
/>
यह KeyAttribute, ऐनिमेशन के पहले 85% हिस्से के लिए @id/credits के alpha को 0.0 पर सेट करता है. यह 0 के ऐल्फ़ा से शुरू होता है. इसका मतलब है कि यह ऐनिमेशन के पहले 85% हिस्से में नहीं दिखेगा.
इस KeyAttribute का आखिरी असर यह होता है कि क्रेडिट, ऐनिमेशन के आखिर में दिखते हैं. इससे ऐसा लगता है कि वे स्क्रीन के दाएं कोने में मौजूद चांद के साथ तालमेल बिठा रहे हैं.
एक व्यू पर एनिमेशन में देरी करके, जबकि दूसरे व्यू को इस तरह से मूव करके, शानदार एनिमेशन बनाए जा सकते हैं. इससे उपयोगकर्ता को ऐसा लगेगा कि एनिमेशन डाइनैमिक है.
इसे आज़माएं
- ऐप्लिकेशन को फिर से चलाएं और ऐनिमेशन देखने के लिए, पांचवें चरण पर जाएं. चांद पर क्लिक करने से, वह
KeyFrameSetमें बताए गए हरKeyAttributeसे गुज़रते हुए, शुरुआत से आखिर तक के रास्ते पर चलेगा.

आपने मून को दो बार पूरा घुमाया है. इसलिए, अब यह दो बार बैक फ़्लिप करेगा. साथ ही, क्रेडिट तब तक नहीं दिखेंगे, जब तक ऐनिमेशन लगभग पूरा न हो जाए.
अपने हिसाब से एक्सप्लोर करें
KeyFrame के आखिरी टाइप पर जाने से पहले, KeyAttributes में मौजूद अन्य स्टैंडर्ड एट्रिब्यूट में बदलाव करके देखें. उदाहरण के लिए, rotation को rotationX में बदलकर देखें कि इससे कैसा ऐनिमेशन बनता है.
यहां स्टैंडर्ड एट्रिब्यूट की सूची दी गई है. इनका इस्तेमाल किया जा सकता है:
android:visibilityandroid:alphaandroid:elevationandroid:rotationandroid:rotationXandroid:rotationYandroid:scaleXandroid:scaleYandroid:translationXandroid:translationYandroid:translationZ
9. कस्टम एट्रिब्यूट बदलना
रिच ऐनिमेशन में, व्यू के रंग या अन्य एट्रिब्यूट में बदलाव किया जाता है. MotionLayout, पिछले टास्क में बताए गए किसी भी स्टैंडर्ड एट्रिब्यूट की वैल्यू बदलने के लिए KeyAttribute का इस्तेमाल कर सकता है. हालांकि, किसी अन्य एट्रिब्यूट की वैल्यू तय करने के लिए, CustomAttribute का इस्तेमाल किया जाता है.
CustomAttribute का इस्तेमाल, सेटर वाली किसी भी वैल्यू को सेट करने के लिए किया जा सकता है. उदाहरण के लिए, CustomAttribute का इस्तेमाल करके, किसी व्यू पर backgroundColor सेट किया जा सकता है. MotionLayout, सेटर को ढूंढने के लिए reflection का इस्तेमाल करेगा. इसके बाद, व्यू को ऐनिमेट करने के लिए, इसे बार-बार कॉल करेगा.
इस चरण में, आपको CustomAttribute का इस्तेमाल करके, चांद पर colorFilter एट्रिब्यूट सेट करना होगा. इससे यहां दिखाया गया ऐनिमेशन बनाया जा सकेगा.

कस्टम एट्रिब्यूट तय करना
- शुरू करने के लिए,
xml/step6.xmlखोलें. इसमें वही ऐनिमेशन है जिसे आपने पिछले चरण में बनाया था. - चांद के रंग बदलने के लिए,
keyFrame="0",keyFrame="50", औरkeyFrame="100".परKeyFrameSetमें दोKeyAttributeऔर एकCustomAttributeजोड़ें

step6.xml
<!-- TODO: Add Custom attributes here -->
<KeyAttribute
motion:framePosition="0"
motion:motionTarget="@id/moon">
<CustomAttribute
motion:attributeName="colorFilter"
motion:customColorValue="#FFFFFF"
/>
</KeyAttribute>
<KeyAttribute
motion:framePosition="50"
motion:motionTarget="@id/moon">
<CustomAttribute
motion:attributeName="colorFilter"
motion:customColorValue="#FFB612"
/>
</KeyAttribute>
<KeyAttribute
motion:framePosition="100"
motion:motionTarget="@id/moon">
<CustomAttribute
motion:attributeName="colorFilter"
motion:customColorValue="#FFFFFF"
/>
</KeyAttribute>
आपने KeyAttribute में CustomAttribute जोड़ा है. CustomAttribute, KeyAttribute के तय किए गए framePosition पर लागू होगा.
CustomAttribute के अंदर, आपको सेट करने के लिए attributeName और एक वैल्यू तय करनी होगी.
motion:attributeName, सेटर का नाम है. इसे इस कस्टम एट्रिब्यूट से कॉल किया जाएगा. इस उदाहरण में,DrawableपरsetColorFilterको कॉल किया जाएगा.motion:custom*Value, नाम में दिए गए टाइप की कस्टम वैल्यू है. इस उदाहरण में, कस्टम वैल्यू के तौर पर रंग दिया गया है.
कस्टम वैल्यू इनमें से किसी भी टाइप की हो सकती हैं:
- रंग
- पूर्णांक
- फ़्लोट
- स्ट्रिंग
- डाइमेंशन
- बूलियन
इस एपीआई का इस्तेमाल करके, MotionLayout किसी भी ऐसे ऑब्जेक्ट को ऐनिमेट कर सकता है जो किसी भी व्यू पर सेटर उपलब्ध कराता है.
इसे आज़माएं
- ऐप्लिकेशन को फिर से चलाएं और ऐनिमेशन देखने के लिए, छठे चरण पर जाएं. चांद पर क्लिक करने से, वह
KeyFrameSetमें बताए गए हरKeyAttributeसे गुज़रते हुए, शुरुआत से आखिर तक के रास्ते पर चलेगा.

ज़्यादा KeyFrames जोड़ने पर, MotionLayout चांद के पाथ को सीधी लाइन से बदलकर एक जटिल कर्व में बदल देता है. साथ ही, ऐनिमेशन के बीच में डबल बैकफ़्लिप, साइज़ में बदलाव, और रंग में बदलाव जोड़ देता है.
असली ऐनिमेशन में, अक्सर एक साथ कई व्यू को ऐनिमेट किया जाता है. साथ ही, उनकी गति और रास्ते को कंट्रोल किया जाता है. हर व्यू के लिए अलग-अलग KeyFrame तय करके, बेहतर ऐनिमेशन बनाए जा सकते हैं. इन ऐनिमेशन में, KeyFrame का इस्तेमाल करके कई व्यू को ऐनिमेट किया जा सकता है.MotionLayout
10. ड्रैग इवेंट और जटिल पाथ
इस चरण में, आपको जटिल पाथ के साथ OnSwipe का इस्तेमाल करने के बारे में जानकारी मिलेगी. अब तक, चांद के ऐनिमेशन को OnClick लिसनर से ट्रिगर किया जाता था और यह तय समय तक चलता था.
OnSwipe का इस्तेमाल करके, जटिल पाथ वाले ऐनिमेशन को कंट्रोल करने के लिए, यह समझना ज़रूरी है कि OnSwipe कैसे काम करता है. जैसे, पिछले कुछ चरणों में आपने मून ऐनिमेशन बनाया था.
पहला चरण: OnSwipe के व्यवहार के बारे में जानें
xml/step7.xmlखोलें औरOnSwipeका मौजूदा एलान ढूंढें.
step7.xml
<!-- Fix OnSwipe by changing touchAnchorSide →
<OnSwipe
motion:touchAnchorId="@id/moon"
motion:touchAnchorSide="bottom"
/>
- अपने डिवाइस पर ऐप्लिकेशन चलाएं और सातवें चरण पर जाएं. देखें कि क्या चंद्रमा को चाप के रास्ते पर खींचकर, एक स्मूद ऐनिमेशन बनाया जा सकता है.
इस ऐनिमेशन को चलाने पर, यह बहुत अच्छा नहीं लगता. चांद के आर्क के सबसे ऊपर पहुंचने के बाद, वह इधर-उधर कूदने लगता है.

बग को समझने के लिए, यह देखें कि जब उपयोगकर्ता आर्क के सबसे ऊपरी हिस्से के ठीक नीचे टच करता है, तो क्या होता है. OnSwipe टैग में motion:touchAnchorSide="bottom" है. इसलिए, MotionLayout पूरे ऐनिमेशन के दौरान उंगली और व्यू के सबसे नीचे वाले हिस्से के बीच की दूरी को एक जैसा रखने की कोशिश करेगा.
हालांकि, चंद्रमा का निचला हिस्सा हमेशा एक ही दिशा में नहीं जाता है. यह ऊपर जाता है और फिर नीचे आता है. इसलिए, जब उपयोगकर्ता आर्क के सबसे ऊपरी हिस्से को पार कर लेता है, तो MotionLayout को यह पता नहीं चलता कि क्या करना है. इस बारे में सोचें. आपको चांद के निचले हिस्से को ट्रैक करना है. जब उपयोगकर्ता यहां टच कर रहा हो, तो इसे कहां रखा जाना चाहिए?

दूसरा चरण: दाईं ओर मौजूद सेक्शन का इस्तेमाल करना
इस तरह की गड़बड़ियों से बचने के लिए, हमेशा ऐसे touchAnchorId और touchAnchorSide चुनें जो पूरे ऐनिमेशन के दौरान एक ही दिशा में आगे बढ़ते हों.
इस ऐनिमेशन में, चंद्रमा की right और left, दोनों साइड स्क्रीन पर एक ही दिशा में आगे बढ़ेंगी.
हालांकि, bottom और top, दोनों की दिशा बदल जाएगी. जब OnSwipe उन्हें ट्रैक करने की कोशिश करेगा, तो दिशा बदलने पर वह भ्रमित हो जाएगा.
- इस ऐनिमेशन को टच इवेंट के हिसाब से दिखाने के लिए,
touchAnchorSideकोrightमें बदलें.
step7.xml
<!-- Fix OnSwipe by changing touchAnchorSide →
<OnSwipe
motion:touchAnchorId="@id/moon"
motion:touchAnchorSide="right"
/>
तीसरा चरण: dragDirection का इस्तेमाल करना
dragDirection को touchAnchorSide के साथ मिलाकर, साइड ट्रैक को सामान्य से अलग दिशा में ले जाया जा सकता है. यह अब भी ज़रूरी है कि touchAnchorSide सिर्फ़ एक दिशा में आगे बढ़े. हालांकि, touchAnchorSide को यह बताया जा सकता है कि किस दिशा में ट्रैक करना है.MotionLayout उदाहरण के लिए, touchAnchorSide="bottom" को रखा जा सकता है, लेकिन dragDirection="dragRight" को जोड़ा जा सकता है. इससे MotionLayout, व्यू के सबसे नीचे वाले हिस्से की पोज़िशन को ट्रैक करेगा. हालांकि, यह सिर्फ़ दाईं ओर जाने पर ही उसकी जगह की जानकारी को ध्यान में रखेगा. यह वर्टिकल मोशन को अनदेखा कर देगा. इसलिए, नीचे का हिस्सा ऊपर और नीचे होने के बावजूद, OnSwipe के साथ सही तरीके से ऐनिमेशन होगा.
- चाँद की गति को सही तरीके से ट्रैक करने के लिए,
OnSwipeको अपडेट करें.
step7.xml
<!-- Using dragDirection to control the direction of drag tracking →
<OnSwipe
motion:touchAnchorId="@id/moon"
motion:touchAnchorSide="bottom"
motion:dragDirection="dragRight"
/>
इसे आज़माएं
- ऐप्लिकेशन को फिर से चलाएं और चांद को पूरे रास्ते पर खींचें. हालांकि, यह एक जटिल आर्क को फ़ॉलो करता है, लेकिन स्वाइप इवेंट के जवाब में
MotionLayoutऐनिमेशन को आगे बढ़ा पाएगा.

11. कोड की मदद से मोशन को चालू करना
MotionLayout का इस्तेमाल, CoordinatorLayout के साथ किया जा सकता है. इससे बेहतर ऐनिमेशन बनाए जा सकते हैं. इस चरण में, MotionLayout का इस्तेमाल करके छोटा किया जा सकने वाला हेडर बनाया जाएगा.
पहला चरण: मौजूदा कोड एक्सप्लोर करना
- शुरू करने के लिए,
layout/activity_step8.xmlखोलें. layout/activity_step8.xmlमें, आपको दिखेगा किCoordinatorLayoutऔरAppBarLayoutपहले से ही बनाया जा चुका है.
activity_step8.xml
<androidx.coordinatorlayout.widget.CoordinatorLayout
...>
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/appbar_layout"
android:layout_width="match_parent"
android:layout_height="180dp">
<androidx.constraintlayout.motion.widget.MotionLayout
android:id="@+id/motion_layout"
... >
...
</androidx.constraintlayout.motion.widget.MotionLayout>
</com.google.android.material.appbar.AppBarLayout>
<androidx.core.widget.NestedScrollView
...
motion:layout_behavior="@string/appbar_scrolling_view_behavior" >
...
</androidx.core.widget.NestedScrollView>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
इस लेआउट में, NestedScrollView और AppBarLayout के बीच स्क्रोल करने की जानकारी शेयर करने के लिए, CoordinatorLayout का इस्तेमाल किया जाता है. इसलिए, जब NestedScrollView ऊपर की ओर स्क्रोल करेगा, तब वह AppBarLayout को बदलाव के बारे में बताएगा. Android पर इस तरह का कोलैप्स होने वाला टूलबार लागू करने का तरीका यही है. इसमें टेक्स्ट की स्क्रॉलिंग, कोलैप्स होने वाले हेडर के साथ "कोऑर्डिनेट" की जाएगी.
@id/motion_layout जिस मोशन सीन की ओर इशारा करता है वह पिछले चरण के मोशन सीन से मिलता-जुलता है. हालांकि, CoordinatorLayout के साथ काम करने के लिए, OnSwipe घोषणा को हटा दिया गया था.
- ऐप्लिकेशन चलाएं और आठवें चरण पर जाएं. आपको दिखेगा कि टेक्स्ट को स्क्रोल करने पर, चंद्रमा नहीं हिलता.
दूसरा चरण: MotionLayout को स्क्रोल करने की सुविधा चालू करना
NestedScrollViewके स्क्रोल होते हीMotionLayoutव्यू को स्क्रोल करने के लिए,MotionLayoutमेंmotion:minHeightऔरmotion:layout_scrollFlagsजोड़ें.
activity_step8.xml
<!-- Add minHeight and layout_scrollFlags to the MotionLayout -->
<androidx.constraintlayout.motion.widget.MotionLayout
android:id="@+id/motion_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
motion:layoutDescription="@xml/step8"
motion:motionDebug="SHOW_PATH"
android:minHeight="80dp"
motion:layout_scrollFlags="scroll|enterAlways|snap|exitUntilCollapsed" >
- ऐप्लिकेशन को फिर से चलाएं और आठवें चरण पर जाएं. आपको दिखेगा कि ऊपर की ओर स्क्रोल करने पर,
MotionLayoutछोटा हो जाता है. हालांकि, स्क्रोल करने के तरीके के आधार पर, ऐनिमेशन में बदलाव नहीं होता है.
तीसरा चरण: कोड की मदद से मोशन को मूव करना
Step8Activity.ktखोलें . स्क्रोल करने की जगह में हुए बदलावों के बारे मेंMotionLayoutको बताने के लिए,coordinateMotion()फ़ंक्शन में बदलाव करें.
Step8Activity.kt
// TODO: set progress of MotionLayout based on an AppBarLayout.OnOffsetChangedListener
private fun coordinateMotion() {
val appBarLayout: AppBarLayout = findViewById(R.id.appbar_layout)
val motionLayout: MotionLayout = findViewById(R.id.motion_layout)
val listener = AppBarLayout.OnOffsetChangedListener { unused, verticalOffset ->
val seekPosition = -verticalOffset / appBarLayout.totalScrollRange.toFloat()
motionLayout.progress = seekPosition
}
appBarLayout.addOnOffsetChangedListener(listener)
}
यह कोड, एक OnOffsetChangedListener को रजिस्टर करेगा. इसे हर बार तब कॉल किया जाएगा, जब उपयोगकर्ता मौजूदा स्क्रोल ऑफ़सेट के साथ स्क्रोल करेगा.
MotionLayout, प्रोग्रेस प्रॉपर्टी सेट करके ट्रांज़िशन को खोजने की सुविधा देता है. verticalOffset और प्रतिशत प्रोग्रेस के बीच बदलने के लिए, कुल स्क्रोल रेंज से भाग दें.
इसे आज़माएं
- ऐप्लिकेशन को फिर से डिप्लॉय करें और आठवें चरण का ऐनिमेशन चलाएं. आपको दिखेगा कि
MotionLayout, स्क्रोल की पोज़िशन के आधार पर ऐनिमेशन को आगे बढ़ाएगा.

MotionLayout का इस्तेमाल करके, कस्टम डाइनैमिक कोलैप्सिंग टूलबार ऐनिमेशन बनाए जा सकते हैं. KeyFrames को एक के बाद एक इस्तेमाल करके, टेक्स्ट को ज़्यादा बोल्ड किया जा सकता है.
12. बधाई हो
इस कोडलैब में, MotionLayout के बुनियादी एपीआई के बारे में बताया गया है.
MotionLayout के ज़्यादा उदाहरण देखने के लिए, आधिकारिक सैंपल देखें. साथ ही, दस्तावेज़ देखना न भूलें!
ज़्यादा जानें
MotionLayout में ऐसी कई सुविधाएं उपलब्ध हैं जिनके बारे में इस कोडलैब में नहीं बताया गया है. जैसे, KeyCycle, की मदद से, दोहराए जाने वाले साइकल वाले पाथ या एट्रिब्यूट को कंट्रोल किया जा सकता है. वहीं, KeyTimeCycle, की मदद से, घड़ी के समय के हिसाब से ऐनिमेशन बनाया जा सकता है. इनके उदाहरणों के लिए सैंपल देखें.
इस कोर्स में मौजूद अन्य कोडलैब के लिंक के लिए, Advanced Android in Kotlin कोडलैब का लैंडिंग पेज देखें.