MotionLayout की मदद से, मोशन और विजेट ऐनिमेशन मैनेज करें

MotionLayout एक ऐसा लेआउट टाइप है जिसकी मदद से, अपने ऐप्लिकेशन में मोशन और विजेट ऐनिमेशन को मैनेज किया जा सकता है. MotionLayout, ConstraintLayout का सबक्लास है और इसकी बेहतर लेआउट सुविधाओं पर आधारित है. ConstraintLayout लाइब्रेरी के हिस्से के तौर पर, MotionLayout सहायता लाइब्रेरी के तौर पर उपलब्ध है.

MotionLayout, लेआउट ट्रांज़िशन और कॉम्प्लेक्स मोशन मैनेजमेंट के बीच के अंतर को कम करता है. साथ ही, प्रॉपर्टी ऐनिमेशन फ़्रेमवर्क, TransitionManager, और CoordinatorLayout के बीच सुविधाओं का एक मिक्स ऑफ़ ऑफ़र करता है.

पहला डायग्राम. टच से कंट्रोल की जाने वाली बुनियादी मोशन.

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

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

डिज़ाइन से जुड़ी बातें

MotionLayout का मकसद, उन यूज़र इंटरफ़ेस (यूआई) एलिमेंट को मूव करना, उनका साइज़ बदलना, और उनमें ऐनिमेशन जोड़ना है जिनसे उपयोगकर्ता इंटरैक्ट करते हैं. जैसे, बटन और टाइटल बार. अपने ऐप में मोशन का इस्तेमाल गैर-ज़रूरी विशेष प्रभाव के रूप में न करें. इसका इस्तेमाल करके उपयोगकर्ताओं को यह समझने में मदद करें कि आपका ऐप्लिकेशन क्या कर रहा है. अपने ऐप्लिकेशन को मोशन के साथ डिज़ाइन करने के बारे में ज़्यादा जानने के लिए, Material Design सेक्शन में मोशन को समझना लेख पढ़ें.

शुरू करें

अपने प्रोजेक्ट में MotionLayout का इस्तेमाल शुरू करने के लिए, यह तरीका अपनाएं.

  1. ConstraintLayout डिपेंडेंसी जोड़ें: अपने प्रोजेक्ट में MotionLayout का इस्तेमाल करने के लिए, अपने ऐप्लिकेशन की build.gradle फ़ाइल में ConstraintLayout 2.0 डिपेंडेंसी जोड़ें. अगर AndroidX का इस्तेमाल किया जा रहा है, तो यह डिपेंडेंसी जोड़ें:

    ग्रूवीKotlin
    dependencies {
        implementation
    "androidx.constraintlayout:constraintlayout:2.2.0-beta01"
       
    // To use constraintlayout in compose
        implementation
    "androidx.constraintlayout:constraintlayout-compose:1.1.0-beta01"
    }
    dependencies {
        implementation
    ("androidx.constraintlayout:constraintlayout:2.2.0-beta01")
       
    // To use constraintlayout in compose
        implementation
    ("androidx.constraintlayout:constraintlayout-compose:1.1.0-beta01")
    }
  2. MotionLayout फ़ाइल बनाएं: MotionLayout, ConstraintLayout का सबसेट है. इसलिए, अपनी लेआउट संसाधन फ़ाइल में क्लास के नाम को बदलकर, किसी भी मौजूदा ConstraintLayout को MotionLayout में बदला जा सकता है. इस बारे में यहां दिए गए उदाहरणों में बताया गया है:

    <!-- before: ConstraintLayout -->
    <androidx.constraintlayout.widget.ConstraintLayout .../>
    <!-- after: MotionLayout -->
    <androidx.constraintlayout.motion.widget.MotionLayout .../>
             
    <!-- before: ConstraintLayout -->
    <android.support.constraint.ConstraintLayout .../>
    <!-- after: MotionLayout -->
    <android.support.constraint.motion.MotionLayout .../>
             

    यहां MotionLayout फ़ाइल का पूरा उदाहरण दिया गया है, जो फ़िगर 1 में दिखाए गए लेआउट को तय करती है:

    <?xml version="1.0" encoding="utf-8"?>
    <!-- activity_main.xml -->
    <androidx.constraintlayout.motion.widget.MotionLayout
       
    xmlns:android="http://schemas.android.com/apk/res/android"
       
    xmlns:app="http://schemas.android.com/apk/res-auto"
       
    xmlns:tools="http://schemas.android.com/tools"
       
    android:id="@+id/motionLayout"
       
    android:layout_width="match_parent"
       
    android:layout_height="match_parent"
       
    app:layoutDescription="@xml/scene_01"
       
    tools:showPaths="true">

       
    <View
           
    android:id="@+id/button"
           
    android:layout_width="64dp"
           
    android:layout_height="64dp"
           
    android:background="@color/colorAccent"
           
    android:text="Button" />

    </androidx.constraintlayout.motion.widget.MotionLayout>
           
    <?xml version="1.0" encoding="utf-8"?>
    <!-- activity_main.xml -->
    <android.support.constraint.motion.MotionLayout
       
    xmlns:android="http://schemas.android.com/apk/res/android"
       
    xmlns:app="http://schemas.android.com/apk/res-auto"
       
    xmlns:tools="http://schemas.android.com/tools"
       
    android:id="@+id/motionLayout"
       
    android:layout_width="match_parent"
       
    android:layout_height="match_parent"
       
    app:layoutDescription="@xml/scene_01"
       
    tools:showPaths="true">

       
    <View
           
    android:id="@+id/button"
           
    android:layout_width="64dp"
           
    android:layout_height="64dp"
           
    android:background="@color/colorAccent"
           
    android:text="Button" />

    </android.support.constraint.motion.MotionLayout>
           
  3. मोशन सीन बनाना: पिछले MotionLayout उदाहरण में, app:layoutDescription एट्रिब्यूट, मोशन सीन का रेफ़रंस देता है. मोशन सीन, एक्सएमएल रिसॉर्स फ़ाइल होती है. अपने <MotionScene> रूट एलिमेंट में, मोशन सीन में उससे जुड़े लेआउट के सभी मोशन ब्यौरे शामिल होते हैं. लेआउट की जानकारी को मोशन के ब्यौरे से अलग रखने के लिए, हर MotionLayout में एक अलग मोशन सीन का रेफ़रंस दिया जाता है. मोशन सीन में मौजूद परिभाषाओं को, MotionLayout में मौजूद मिलती-जुलती परिभाषाओं के मुकाबले प्राथमिकता दी जाती है.

    यहां मोशन सीन की एक फ़ाइल का उदाहरण दिया गया है. इसमें पहली इमेज में बेसिक हॉरिज़ॉन्टल मोशन के बारे में बताया गया है:

    <?xml version="1.0" encoding="utf-8"?>
    <MotionScene xmlns:android="http://schemas.android.com/apk/res/android"
       
    xmlns:motion="http://schemas.android.com/apk/res-auto">

       
    <Transition
           
    motion:constraintSetStart="@+id/start"
           
    motion:constraintSetEnd="@+id/end"
           
    motion:duration="1000">
           
    <OnSwipe
               
    motion:touchAnchorId="@+id/button"
               
    motion:touchAnchorSide="right"
               
    motion:dragDirection="dragRight" />
       
    </Transition>

       
    <ConstraintSet android:id="@+id/start">
           
    <Constraint
               
    android:id="@+id/button"
               
    android:layout_width="64dp"
               
    android:layout_height="64dp"
               
    android:layout_marginStart="8dp"
               
    motion:layout_constraintBottom_toBottomOf="parent"
               
    motion:layout_constraintStart_toStartOf="parent"
               
    motion:layout_constraintTop_toTopOf="parent" />
       
    </ConstraintSet>

       
    <ConstraintSet android:id="@+id/end">
           
    <Constraint
               
    android:id="@+id/button"
               
    android:layout_width="64dp"
               
    android:layout_height="64dp"
               
    android:layout_marginEnd="8dp"
               
    motion:layout_constraintBottom_toBottomOf="parent"
               
    motion:layout_constraintEnd_toEndOf="parent"
               
    motion:layout_constraintTop_toTopOf="parent" />
       
    </ConstraintSet>

    </MotionScene>
       

    यहां दी गई बातों का ध्यान रखें:

    • <Transition> में मोशन की बुनियादी परिभाषा होती है.

      • motion:constraintSetStart और motion:constraintSetEnd, मोशन के एंडपॉइंट के रेफ़रंस हैं. ये एंडपॉइंट, मोशन सीन में बाद में <ConstraintSet> एलिमेंट में तय किए जाते हैं.

      • motion:duration से यह पता चलता है कि मोशन पूरा होने में कितने मिलीसेकंड लगते हैं.

    • <OnSwipe> इसकी मदद से, मोशन के लिए टच कंट्रोल बनाया जा सकता है.

      • motion:touchAnchorId से उस व्यू का पता चलता है जिसे उपयोगकर्ता स्वाइप और खींच सकता है.

      • motion:touchAnchorSide का मतलब है कि व्यू को दाईं ओर से खींचा जा रहा है.

      • motion:dragDirection, प्रोग्रेस के हिसाब से, खींचने और छोड़ने की दिशा बताता है. उदाहरण के लिए, motion:dragDirection="dragRight" का मतलब है कि व्यू को दाईं ओर खींचने पर, प्रोग्रेस बढ़ जाती है.

    • <ConstraintSet> यहां आपको अपनी गति के बारे में बताने वाली अलग-अलग शर्तें तय करनी होती हैं. इस उदाहरण में, आपकी मोशन के हर एंडपॉइंट के लिए एक <ConstraintSet> तय किया गया है. ये एंडपॉइंट, app:layout_constraintTop_toTopOf="parent" और app:layout_constraintBottom_toBottomOf="parent" का इस्तेमाल करके वर्टिकल तौर पर केंद्र में होते हैं. हॉरिज़ॉन्टल तौर पर, एंडपॉइंट स्क्रीन के बाईं और दाईं ओर मौजूद होते हैं.

    मोशन सीन में इस्तेमाल किए जा सकने वाले अलग-अलग एलिमेंट के बारे में ज़्यादा जानने के लिए, MotionLayout के उदाहरण देखें.

इंटरपोलेट किए गए एट्रिब्यूट

मोशन सीन वाली फ़ाइल में, ConstraintSet एलिमेंट में ऐसे अन्य एट्रिब्यूट हो सकते हैं जो ट्रांज़िशन के दौरान इंटरपोलेट किए जाते हैं. पोज़िशन और सीमाओं के अलावा, MotionLayout इन एट्रिब्यूट को इंटरपोल करता है:

  • alpha
  • visibility
  • elevation
  • rotation, rotationX, rotationY
  • translationX, translationY, translationZ
  • scaleX, scaleY

कस्टम विशेषताएं

<Constraint> में, <CustomAttribute> एलिमेंट का इस्तेमाल उन एट्रिब्यूट के लिए ट्रांज़िशन तय करने के लिए किया जा सकता है जो सिर्फ़ पोज़िशन या View एट्रिब्यूट से नहीं जुड़े हैं.

<Constraint
   
android:id="@+id/button" ...>
   
<CustomAttribute
       
motion:attributeName="backgroundColor"
       
motion:customColorValue="#D81B60"/>

</Constraint>

<CustomAttribute> में दो एट्रिब्यूट होते हैं:

  • motion:attributeName ज़रूरी है और यह किसी ऐसे ऑब्जेक्ट से मेल खाना चाहिए जिसमें getter और setter तरीके हों. गेट्टर और सेटर, किसी खास पैटर्न से मेल खाने चाहिए. उदाहरण के लिए, backgroundColor काम करता है, क्योंकि व्यू में getBackgroundColor() और setBackgroundColor() तरीके मौजूद हैं.
  • आपको जो दूसरा एट्रिब्यूट देना होगा वह वैल्यू टाइप पर आधारित होता है. इस्तेमाल किए जा सकने वाले इन टाइप में से कोई चुनें:
    • motion:customColorValue रंगों के लिए
    • पूर्णांक के लिए motion:customIntegerValue
    • motion:customFloatValue फ़्लोट के लिए
    • स्ट्रिंग के लिए motion:customStringValue
    • motion:customDimension डाइमेंशन के लिए
    • बूलियन के लिए motion:customBoolean

कस्टम एट्रिब्यूट तय करते समय, शुरुआती और आखिरी <ConstraintSet> एलिमेंट में एंडपॉइंट वैल्यू को तय करें.

बैकग्राउंड का रंग बदलें

पिछले उदाहरण के आधार पर, मान लें कि आपको व्यू के रंगों को उसकी गति के हिस्से के तौर पर बदलना है, जैसा कि दूसरे चित्र में दिखाया गया है.

दूसरी इमेज. व्यू के आगे-पीछे होने पर, उसके बैकग्राउंड का रंग बदल जाता है.

हर ConstraintSet एलिमेंट में <CustomAttribute> एलिमेंट जोड़ें, जैसा कि इस कोड स्निपेट में दिखाया गया है:

<ConstraintSet android:id="@+id/start">
   
<Constraint
       
android:id="@+id/button"
       
android:layout_width="64dp"
       
android:layout_height="64dp"
       
android:layout_marginStart="8dp"
       
motion:layout_constraintBottom_toBottomOf="parent"
       
motion:layout_constraintStart_toStartOf="parent"
       
motion:layout_constraintTop_toTopOf="parent">
       
<CustomAttribute
           
motion:attributeName="backgroundColor"
           
motion:customColorValue="#D81B60" />

   
</Constraint>
</ConstraintSet>

<ConstraintSet android:id="@+id/end">
   
<Constraint
       
android:id="@+id/button"
       
android:layout_width="64dp"
       
android:layout_height="64dp"
       
android:layout_marginEnd="8dp"
       
motion:layout_constraintBottom_toBottomOf="parent"
       
motion:layout_constraintEnd_toEndOf="parent"
       
motion:layout_constraintTop_toTopOf="parent">
       
<CustomAttribute
           
motion:attributeName="backgroundColor"
           
motion:customColorValue="#9999FF" />

   
</Constraint>
</ConstraintSet>

MotionLayout के अन्य एट्रिब्यूट

पिछले उदाहरण में दिए गए एट्रिब्यूट के अलावा, MotionLayout में ऐसे अन्य एट्रिब्यूट भी हैं जिनके बारे में आपको बताना पड़ सकता है:

  • app:applyMotionScene="boolean" से पता चलता है कि मोशन सीन लागू करना है या नहीं. इस एट्रिब्यूट के लिए डिफ़ॉल्ट वैल्यू true है.
  • app:showPaths="boolean" से पता चलता है कि ऐनिमेशन चलने के दौरान, ऐनिमेशन पाथ दिखाने हैं या नहीं. इस एट्रिब्यूट की डिफ़ॉल्ट वैल्यू false है.
  • app:progress="float" की मदद से, ट्रांज़िशन की प्रोग्रेस के बारे में साफ़ तौर पर बताया जा सकता है. 0 (ट्रांज़िशन की शुरुआत) से लेकर 1 (ट्रांज़िशन के खत्म होने तक) तक, किसी भी फ़्लोटिंग-पॉइंट वैल्यू का इस्तेमाल किया जा सकता है.
  • app:currentState="reference" की मदद से, आपको कोई खास ConstraintSet बनाने की सुविधा मिलती है.
  • app:motionDebug की मदद से, ऐक्शन के बारे में डीबग करने से जुड़ी ज़्यादा जानकारी देखी जा सकती है. इसकी वैल्यू "SHOW_PROGRESS", "SHOW_PATH" या "SHOW_ALL" हो सकती हैं.

अन्य संसाधन

MotionLayout के बारे में ज़्यादा जानकारी के लिए, ये संसाधन देखें: