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

Compose को आज़माएं
Android के लिए, Jetpack Compose को यूज़र इंटरफ़ेस (यूआई) टूलकिट के तौर पर इस्तेमाल करने का सुझाव दिया जाता है. Compose में ऐनिमेशन इस्तेमाल करने का तरीका जानें.

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

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

पहली इमेज. टच कंट्रोल से होने वाली सामान्य हलचल.

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

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

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

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

शुरू करें

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

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

    ग्रूवी

    dependencies {
        implementation "androidx.constraintlayout:constraintlayout:2.2.1"
        // To use constraintlayout in compose
        implementation "androidx.constraintlayout:constraintlayout-compose:1.1.1"
    }

    Kotlin

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

    AndroidX

    <!-- 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 फ़ाइल का पूरा उदाहरण दिया गया है. इससे, पहली इमेज में दिखाया गया लेआउट तय होता है:

    AndroidX

    <?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. MotionScene बनाएं: पिछले 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 for colors
    • पूर्णांकों के लिए 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 के बारे में ज़्यादा जानकारी के लिए, ये संसाधन देखें: