1. शुरू करने से पहले
यह कोडलैब, Kotlin के ऐडवांस Android कोर्स का हिस्सा है. अगर कोड लैब को क्रम से लगाया जाता है, तो आपको इस कोर्स से सबसे ज़्यादा फ़ायदा मिलेगा. हालांकि, ऐसा करना ज़रूरी नहीं है. सभी कोर्स कोडलैब, Kotlin कोडलैब में बेहतर Android लैंडिंग पेज पर मौजूद हैं.
MotionLayout एक लाइब्रेरी है, जिससे आप अपने Android ऐप्लिकेशन में रिच मोशन जोड़ सकते हैं. यह ConstraintLayout, पर आधारित है. इसकी मदद से, ऐसी किसी भी चीज़ को ऐनिमेट किया जा सकता है जिसे ConstraintLayout का इस्तेमाल करके बनाया जा सकता है.
MotionLayout का इस्तेमाल, एक ही समय पर एक से ज़्यादा व्यू की जगह, साइज़, विज़िबिलिटी, ऐल्फ़ा, रंग, ऊंचाई, घुमाव, और अन्य एट्रिब्यूट को ऐनिमेट करने के लिए किया जा सकता है. डिक्लेरेटिव एक्सएमएल का इस्तेमाल करके, कई व्यू के साथ कोऑर्डिनेटेड ऐनिमेशन बनाए जा सकते हैं, जिन्हें कोड में हासिल करना मुश्किल होता है.
किसी ऐप्लिकेशन के अनुभव को बेहतर बनाने के लिए ऐनिमेशन एक बेहतरीन तरीका है. ऐनिमेशन का इस्तेमाल इन कामों के लिए किया जा सकता है:
- बदलाव दिखाएं— अलग-अलग स्थितियों के हिसाब से ऐनिमेशन करने पर, उपयोगकर्ता आपके यूज़र इंटरफ़ेस (यूआई) में आम तौर पर होने वाले बदलावों को ट्रैक कर सकता है.
- ध्यान खींचें—अहम यूज़र इंटरफ़ेस (यूआई) एलिमेंट पर ध्यान खींचने के लिए, ऐनिमेशन का इस्तेमाल करें.
- सुंदर डिज़ाइन बनाएं—डिज़ाइन में असरदार मोशन से ऐप्लिकेशन शानदार दिखते हैं.
ज़रूरी शर्तें
यह कोडलैब, उन डेवलपर के लिए बनाया गया है जिन्हें Android डेवलपमेंट का कुछ अनुभव है. इस कोडलैब के पूरा होने की कोशिश करने से पहले, आपको यह करना चाहिए:
- किसी गतिविधि और बेसिक लेआउट की मदद से ऐप्लिकेशन बनाने का तरीका जानें. साथ ही, Android Studio का इस्तेमाल करके उसे किसी डिवाइस या एम्युलेटर पर चलाने का तरीका जानें. ConstraintLayoutके बारे में जानें.ConstraintLayoutके बारे में ज़्यादा जानने के लिए, Constraint लेआउट कोडलैब को पढ़ें.
आपको क्या करना होगा
- 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 का सब-क्लास है. इसलिए, ऐनिमेशन जोड़ते समय यह पहले जैसी सभी सुविधाओं के साथ काम करता है. 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को चुना गया है.startऔरendके बीच ट्रांज़िशन चुनने के लिए, उनके बीच दिखने वाले ऐरो पर क्लिक करें.
- सेक्शन – खास जानकारी के नीचे एक सेक्शन विंडो है, जो चुने गए मौजूदा खास जानकारी आइटम के आधार पर बदलती है. इस इमेज में, चुनने वाली विंडो में startConstraintSetकी जानकारी दिख रही है.
- एट्रिब्यूट – एट्रिब्यूट पैनल, खास जानकारी या चुनने वाली विंडो से, चुने गए मौजूदा आइटम की विशेषताओं को दिखाता है और उनमें बदलाव करने की सुविधा देता है. इस इमेज में, यह startConstraintSetके लिए एट्रिब्यूट दिखा रहा है.
तीसरा चरण: शुरू और खत्म होने के कंस्ट्रेंट तय करना
सभी एनिमेशन को प्रारंभ और अंत के रूप में परिभाषित किया जा सकता है. शुरुआत में यह बताया जाता है कि ऐनिमेशन से पहले स्क्रीन कैसी दिखती है और आखिर में यह पता चलता है कि ऐनिमेशन पूरा होने के बाद स्क्रीन कैसी दिखेगी. यह MotionLayout की ज़िम्मेदारी है कि यह पता लगाएं कि शुरुआत और आखिर में (समय के साथ) कैसे ऐनिमेट किया जाए.
MotionScene, शुरू और खत्म होने की स्थितियां बताने के लिए ConstraintSet टैग का इस्तेमाल करता है. ConstraintSet ऐसा लगता है, जो व्यू पर लागू किए जा सकने वाले कंस्ट्रेंट का एक सेट है. इसमें चौड़ाई, ऊंचाई, और ConstraintLayout कंस्ट्रेंट शामिल हैं. इसमें alpha जैसे कुछ एट्रिब्यूट भी शामिल हैं. इसमें व्यू शामिल नहीं होते, सिर्फ़ उन व्यू पर कंस्ट्रेंट होता है.
ConstraintSet में दिए गए कंस्ट्रेंट, लेआउट फ़ाइल में दिए गए कंस्ट्रेंट को बदल देंगे. अगर आपने लेआउट और MotionScene, दोनों में कंस्ट्रेंट तय किए हैं, तो सिर्फ़ MotionScene में कंस्ट्रेंट लागू होंगे.
इस चरण में, आपको स्टार व्यू को स्क्रीन में सबसे ऊपर शुरू करने और स्क्रीन के निचले सिरे पर पूरा करने के लिए सीमित करना होगा.
आप यह चरण या तो मोशन एडिटर का इस्तेमाल करके या सीधे activity_step1_scene.xml के टेक्स्ट में बदलाव करके पूरा कर सकते हैं.
- खास जानकारी वाले पैनल में, startConstraintSet को चुनें

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

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

- इस रुकावट के लिए मोशन एडिटर ने जो कोड जनरेट किया है उसे देखने के लिए 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/start का id होता है और MotionLayout के सभी व्यू पर लागू होने वाली सभी पाबंदियों के बारे में पता चलता है. इस MotionLayout में सिर्फ़ एक व्यू है, इसलिए इसे सिर्फ़ एक Constraint की ज़रूरत है.
ConstraintSet में मौजूद Constraint, ऐसे व्यू का आईडी बताता है जिसे कंस्ट्रेंट किया जा रहा है. इसका मतलब है कि @id/red_star activity_step1.xml में तय किया गया है. ध्यान रखें कि Constraint टैग सिर्फ़ कंस्ट्रेंट और लेआउट की जानकारी देते हैं. Constraint टैग को यह पता नहीं है कि उसे ImageView पर लागू किया जा रहा है.
यह कंस्ट्रेंट, ऊंचाई, चौड़ाई, और दो अन्य कंस्ट्रेंट के बारे में बताता है जो red_star व्यू को उसके पैरंट के टॉप स्टार्ट तक सीमित करने के लिए ज़रूरी होते हैं.
- खास जानकारी वाले पैनल में, endConstraintSet को चुनें.

- end- ConstraintSetमें- 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 फ़ाइल बनाई है, तो मोशन एडिटर ने हमारे लिए डिफ़ॉल्ट रूप से एक ट्रांज़िशन बनाया है. जनरेट किया गया ट्रांज़िशन देखने के लिए, 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 पर हुए क्लिक इवेंट का जवाब देने के लिए कहा जाए.
- मोशन एडिटर खोलें. इसके बाद, खास जानकारी देने वाले पैनल में, शुरू और खत्म होने के बीच के ऐरो पर क्लिक करके ट्रांज़िशन चुनें.

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

- क्लिक टू क्लिक को red_starमें बदलें.

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

- खास जानकारी वाले पैनल में ट्रांज़िशन चुने जाने के बाद, उस ऑनक्लिक हैंडलर में 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, <OnClick> टैग का इस्तेमाल करके, MotionLayout को क्लिक इवेंट के जवाब में ऐनिमेशन चलाने के लिए कहता है. हर एट्रिब्यूट को देखें:
- 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 नाम का इस्तेमाल और दोनों के लिए किया गया है. इन दोनों का इस्तेमाल कंस्ट्रेंट के लिए किया गया है. अंतर को समझाने के लिए, layout_constraintStart में start का मतलब "शुरू" से है जो बाईं से दाईं ओर बाईं ओर और दाईं से बाईं भाषा में दाईं ओर मौजूद है. start कंस्ट्रेंट सेट, ऐनिमेशन के शुरू होने के बारे में बताता है.
end 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 में alpha प्रॉपर्टी @id/right_start और @id/left_star पर सेट है, इसलिए ऐनिमेशन के आगे बढ़ने पर दोनों व्यू फ़ेड इन हो जाएंगे.
उपयोगकर्ता के स्वाइप करने पर ऐनिमेट किया जा रहा है
MotionLayout, फ़िज़िक्स पर आधारित "फ़्लिंग" बनाने के लिए, उपयोगकर्ता को खींचकर छोड़ने वाले इवेंट या स्वाइप को ट्रैक कर सकता है ऐनिमेशन. इसका मतलब है कि अगर उपयोगकर्ता उन्हें फ़्लेक्ट करता है, तो व्यू वैसे ही चलते रहेंगे जैसे किसी जगह पर लुढ़कते समय वे किसी चीज़ की तरह धीरे-धीरे रुकते हैं. Transition में, OnSwipe टैग के साथ इस तरह का ऐनिमेशन जोड़ा जा सकता है.
- OnSwipeटैग को- <OnSwipe motion:touchAnchorId="@id/red_star" />से जोड़ने के लिए, TODO की जगह नई जानकारी जोड़ें.
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 के बीच की दूरी को स्थिर रखेगा. उदाहरण के लिए, अगर वे ऐंकर साइड से 100dp की दूरी को छूते हैं, तो MotionLayout पूरे ऐनिमेशन के लिए उस साइड को 100dp से दूर रखेगा.
इसे आज़माएं
- ऐप्लिकेशन को फिर से चलाएं और चरण 2 वाली स्क्रीन खोलें. आपको ऐनिमेशन दिखेगा.
- "फ़्लिंग करें" आज़माएं या ऐनिमेशन के बीच में अपनी उंगली रखकर, यह एक्सप्लोर करें कि 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 का चाइल्ड है और यह KeyPosition जैसे सभी KeyFrames का सेट है, जिसे ट्रांज़िशन के दौरान लागू किया जाना चाहिए.
MotionLayout शुरुआत और आखिर के बीच चांद के रास्ते का पता लगा रहा है. इसलिए, यह KeyFrameSet में बताए गए KeyPosition के हिसाब से पाथ में बदलाव करता है. आप ऐप्लिकेशन को फिर से चलाकर देख सकते हैं कि इससे पाथ में कैसे बदलाव होता है.
KeyPosition में ऐसे कई एट्रिब्यूट होते हैं जो पाथ में बदलाव करने के तरीके की जानकारी देते हैं. इनमें सबसे ज़रूरी बदलाव ये हैं:
- framePosition, 0 से 100 के बीच की कोई संख्या होती है. यह बताता है कि ऐनिमेशन में कब- KeyPositionको लागू किया जाना चाहिए. इसमें 1 का मतलब है कि ऐनिमेशन में 1% और ऐनिमेशन में 99 का मतलब 99% है. इसलिए, अगर वैल्यू 50 है, तो इसे बीच में लागू करें.
- motionTargetवह व्यू है जिसके लिए यह- KeyPosition, पाथ में बदलाव करता है.
- KeyPosition,- keyPositionTypeके हिसाब से पाथ में बदलाव करता है. यह- parentRelative,- pathRelativeया- deltaRelativeहो सकता है (जैसा कि अगले चरण में बताया गया है).
- framePositionपर- percentX | percentY, पाथ में कितने बदलाव करना है (0.0 और 1.0 के बीच के मान, नेगेटिव वैल्यू और 1 से ज़्यादा वैल्यू वाले).
आप इसे इस तरह समझ सकते हैं: framePosition पर keyPositionType के तय किए गए निर्देशांक के मुताबिक percentX या percentY के पाथ को बदलकर motionTarget के पाथ में बदलाव करें."
डिफ़ॉल्ट रूप से, 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 के पाथ को parentRelative (पूरे MotionLayout) के निर्देशांकों के अनुसार 50% Y (स्क्रीन के आधे नीचे) आगे ले जाकर बदलें."
इसलिए, ऐनिमेशन के आधे रास्ते में, चांद को KeyPosition से गुजरना होगा, जो स्क्रीन पर 50% नीचे था. यह 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 से बड़ी वैल्यू का इस्तेमाल करने की अनुमति देते हैं. उदाहरण के लिए, -2.0 की percentX वैल्यू का मतलब होगा कि X ऐक्सिस की उलट दिशा में दो बार जाएं.
अगर आपको यह सब कुछ बहुत ही Algebra क्लास जैसा लगता है, तो नीचे दी गई तस्वीरें देखें!
ParentRelative कोऑर्डिनेट

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

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

MotionLayout में आखिरी निर्देशांक सिस्टम pathRelative है. यह बाकी दो से काफ़ी अलग है, क्योंकि X ऐक्सिस, मोशन पाथ को शुरू से आखिर तक फ़ॉलो करता है. इसलिए, (0,0) शुरुआती पोज़िशन है और (1,0) आखिरी पोज़िशन है.
आपको ऐसा क्यों करना चाहिए? पहली नज़र में इसे देखना हैरानी की बात है, खास तौर पर जब यह निर्देशांक सिस्टम स्क्रीन निर्देशांक सिस्टम के साथ अलाइन नहीं होता है.
ऐसा लगता है कि pathRelative कुछ चीज़ों के लिए वाकई काम का है.
- ऐनिमेशन के दौरान किसी व्यू की रफ़्तार बढ़ाना, कम करना या रोकना. X डाइमेंशन हमेशा उस पाथ से मेल खाएगा जिसे व्यू ने चुना है. इसलिए, pathRelativeKeyPositionका इस्तेमाल करके यह तय किया जा सकता है कि उस पाथ के किसी खास पॉइंट पर किसframePositionतक पहुंचा जा सकता है. इसलिए,framePosition="50"परpercentX="0.1"के साथKeyPositionकी वजह से, ऐनिमेशन को 50% समय में यात्रा के पहले 10% समय में मदद मिलेगी.
- पाथ में सूक्ष्म आर्क जोड़ना. 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 हर KeyPosition को बताए गए framePosition पर लागू करेगा और जानें कि एक ऐसा मोशन मूव कैसे बनाया जाए जो KeyPositions के सभी हिस्सों से गुज़रता हो.
इसे आज़माएं
- ऐप्लिकेशन को फिर से चलाएं. ऐनिमेशन का इस्तेमाल कैसे किया जाता है, यह देखने के लिए चौथे चरण पर जाएं. जब आप चांद पर क्लिक करते हैं, तो यह शुरू से आखिर तक पाथ फ़ॉलो करता है और KeyFrameSetमें बताए गए हरKeyPositionसे गुज़रता है.
अपने-आप एक्सप्लोर करें
इससे पहले कि आप दूसरी तरह के 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खोलें. इसमें वही ऐनिमेशन है जो आपने पिछले चरण में बनाया था. विविधता के लिए, यह स्क्रीन बैकग्राउंड के तौर पर अलग स्पेस तस्वीर का इस्तेमाल करती है.
- चांद का आकार बढ़ाने और उसे घुमाने के लिए, KeyFrameSetमेंkeyFrame="50"औरkeyFrame="100"पर दो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तय करें. इससे यह पक्का होता है किalpha,keyPosition="85"तक 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 का आखिरी असर यह है कि क्रेडिट, ऐनिमेशन के आखिर में दिखते हैं. इससे स्क्रीन के दाएं कोने में चांद सेट होने का पता चलता है.
एक व्यू में ऐनिमेशन को देर से दिखाकर, दूसरे व्यू में इस तरह से बदलाव करके, बेहतरीन ऐनिमेशन बनाए जा सकते हैं. इनसे दर्शक को ऐनिमेशन का एहसास होता है.
इसे आज़माएं
- ऐनिमेशन को काम करते हुए देखने के लिए ऐप्लिकेशन को फिर से चलाएं और पांचवे चरण पर जाएं. जब आप चांद पर क्लिक करेंगे, तो यह शुरू से आखिर तक के पाथ को फ़ॉलो करेगा और हर KeyAttributeसे होकर गुज़रेगा, जिसकी जानकारीKeyFrameSetमें दी गई है.

चांद को दो पूरे सर्कल में घुमाने की वजह से, अब इसमें डबल बैक फ़्लिप किया जाएगा. साथ ही, क्रेडिट तब तक देर से दिखेगा, जब तक ऐनिमेशन पूरा नहीं हो जाता.
अपने-आप एक्सप्लोर करें
KeyFrame के आखिरी टाइप पर जाने से पहले, KeyAttributes में मौजूद अन्य स्टैंडर्ड एट्रिब्यूट में बदलाव करें. उदाहरण के लिए, rotation से rotationX में बदलाव करके देखें कि इससे कौनसा ऐनिमेशन बनता है.
यहां उन मानक विशेषताओं की सूची दी गई है जिन्हें आप आज़मा सकते हैं:
- android:visibility
- android:alpha
- android:elevation
- android:rotation
- android:rotationX
- android:rotationY
- android:scaleX
- android:scaleY
- android:translationX
- android:translationY
- android:translationZ
9. कस्टम विशेषताएं बदलना
रिच ऐनिमेशन में, व्यू का रंग या दूसरे एट्रिब्यूट बदलना शामिल होता है. MotionLayout, पिछले टास्क में बताए गए किसी भी स्टैंडर्ड एट्रिब्यूट को बदलने के लिए, KeyAttribute का इस्तेमाल कर सकता है. हालांकि, किसी अन्य एट्रिब्यूट की जानकारी देने के लिए, CustomAttribute का इस्तेमाल किया जा सकता है.
CustomAttribute का इस्तेमाल ऐसी किसी भी वैल्यू को सेट करने के लिए किया जा सकता है जिसमें सेटर हो. उदाहरण के लिए, CustomAttribute का इस्तेमाल करके, किसी व्यू पर backgroundColor सेट करने की सुविधा उपलब्ध है. MotionLayout सेटर को ढूंढने के लिए रिफ़्लेक्शन का इस्तेमाल करेगा. इसके बाद, व्यू को ऐनिमेट करने के लिए उसे बार-बार कॉल करेगा.
इस चरण में, आपको CustomAttribute का इस्तेमाल करके, चांद पर colorFilter एट्रिब्यूट को सेट करके यहां दिखाया गया ऐनिमेशन बनाना होगा.

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

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 ऐसी किसी भी चीज़ को ऐनिमेट कर सकता है जो किसी भी व्यू पर सेटर उपलब्ध कराती है.
इसे आज़माएं
- ऐनिमेशन को काम करते हुए देखने के लिए, ऐप्लिकेशन को फिर से चलाएं और छठे चरण पर जाएं. जब आप चांद पर क्लिक करेंगे, तो यह शुरू से आखिर तक के पाथ को फ़ॉलो करेगा और हर KeyAttributeसे होकर गुज़रेगा, जिसकी जानकारीKeyFrameSetमें दी गई है.

जब ज़्यादा KeyFrames जोड़े जाते हैं, तो MotionLayout चांद के रास्ते को एक सीधी लाइन से जटिल कर्व में बदल देता है. साथ ही, ऐनिमेशन के बीच में डबल बैकफ़्लिप, साइज़, और रंग बदलने की सुविधा जोड़ देता है.
असल ऐनिमेशन में, आप अक्सर एक ही समय में कई व्यू को ऐनिमेट करेंगे. इससे, अलग-अलग पाथ और स्पीड में उनकी गति को कंट्रोल किया जा सकेगा. हर व्यू के लिए अलग 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 को 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 जिस मोशन सीन की तरफ़ इशारा करता है वह आखिरी चरण में बताए गए मोशन सीन के जैसा ही है. हालांकि, OnSwipe के एलान को हटा दिया गया था, ताकि यह CoordinatorLayout के साथ काम कर सके.
- ऐप्लिकेशन चलाएं और आठवें चरण पर जाएं. आप देखते हैं कि जब आप लेख को स्क्रॉल करते हैं, तो चांद नहीं चलता है.
दूसरा चरण: MotionLayout को स्क्रोल करना
- NestedScrollViewके स्क्रोल करते ही- MotionLayoutव्यू को स्क्रोल करने के लिए,- motion:minHeightऔर- motion:layout_scrollFlagsको- MotionLayoutमें जोड़ें.
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, जो आपको घड़ी के समय के आधार पर ऐनिमेट करने देता है. हर उदाहरण के लिए दिए गए सैंपल देखें.
इस कोर्स में अन्य कोडलैब के लिंक के लिए, Kotlin कोडलैब में बेहतर Android का लैंडिंग पेज देखें.