MotionLayout-এর সাহায্যে মোশন ও উইজেট অ্যানিমেশন ম্যানেজ করা

Compose-এর মাধ্যমে চেষ্টা করুন
Jetpack Compose হল Android-এর জন্য সাজেস্ট করা UI টুলকিট। Compose-এ কীভাবে অ্যানিমেশন ব্যবহার করতে হয় তা জানুন।

MotionLayout হল একটি লেআউটের ধরন যা আপনার অ্যাপে মোশন এবং উইজেট অ্যানিমেশন ম্যানেজ করতে সাহায্য করে। MotionLayout হল ConstraintLayout-এর একটি সাবক্লাস এবং এর সমৃদ্ধ লেআউট ক্ষমতার উপর ভিত্তি করে তৈরি করা হয়েছে। ConstraintLayout লাইব্রেরির অংশ হিসেবে, MotionLayout সাপোর্ট লাইব্রেরি হিসেবে উপলভ্য।

MotionLayout লেআউট ট্রানজিশন ও জটিল মোশন হ্যান্ডলিংয়ের মধ্যে পার্থক্য দূর করে, প্রপার্টি অ্যানিমেশন ফ্রেমওয়ার্ক, TransitionManager এবং CoordinatorLayout-এর মধ্যে ফিচারের মিশ্রণ অফার করে।

ছবি ১. বেসিক টাচ-কন্ট্রোলড মোশন।

লেআউটের মধ্যে ট্রানজিশন বর্ণনা করার পাশাপাশি, MotionLayout আপনাকে যেকোনও লেআউট প্রপার্টি অ্যানিমেট করতে দেয়। এছাড়াও, এটি সহজাতভাবে সিক করা যায় এমন ট্রানজিশন সাপোর্ট করে। এর অর্থ হল, আপনি টাচ ইনপুটের মতো কোনও শর্তের ভিত্তিতে ট্রানজিশনের মধ্যে যেকোনও পয়েন্ট ঝটপট দেখাতে পারবেন। MotionLayout-এ কীফ্রেমও কাজ করে, যা আপনার প্রয়োজন অনুসারে সম্পূর্ণ কাস্টমাইজ করা ট্রানজিশন চালু করে।

MotionLayout সম্পূর্ণভাবে ডিক্লারেটিভ, অর্থাৎ আপনি XML-এ যেকোনও ট্রানজিশন বর্ণনা করতে পারবেন, তা যতই জটিল হোক না কেন।

ডিজাইন সংক্রান্ত বিবেচনা

MotionLayout-এর উদ্দেশ্য হল UI এলিমেন্ট সরানো, ছোট বড় করা এবং অ্যানিমেট করা, যার সাথে ব্যবহারকারীরা ইন্টার‍্যাক্ট করেন, যেমন বোতাম এবং টাইটেল বার। আপনার অ্যাপে মোশনকে অপ্রয়োজনীয় বিশেষ এফেক্ট হিসেবে ব্যবহার করবেন না। আপনার অ্যাপ কী করছে তা ব্যবহারকারীদের বুঝতে সাহায্য করার জন্য এটি ব্যবহার করুন। মোশন সহ আপনার অ্যাপ ডিজাইন করার ব্যাপারে আরও তথ্যের জন্য, মেটেরিয়াল ডিজাইন বিভাগের মোশন বোঝা দেখুন।

শুরু করুন

আপনার প্রোজেক্টে MotionLayout ব্যবহার শুরু করতে এইসব ধাপ অনুসরণ করুন।

  1. ConstraintLayout ডিপেন্ডেন্সি যোগ করুন: আপনার প্রোজেক্টে MotionLayout ব্যবহার করতে, আপনার অ্যাপের build.gradle ফাইলে ConstraintLayout 2.0 ডিপেন্ডেন্সি যোগ করুন। আপনি AndroidX ব্যবহার করলে, নিম্নলিখিত ডিপেন্ডেন্সি যোগ করুন:

    গ্রোভি

    dependencies {
        implementation "androidx.constraintlayout:constraintlayout:2.2.2"
        // To use constraintlayout in compose
        implementation "androidx.constraintlayout:constraintlayout-compose:1.1.2"
    }

    কোটলিন

    dependencies {
        implementation("androidx.constraintlayout:constraintlayout:2.2.2")
        // To use constraintlayout in compose
        implementation("androidx.constraintlayout:constraintlayout-compose:1.1.2")
    }
  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 অ্যাট্রিবিউট একটি মোশন সিন রেফারেন্স করে। মোশন সিন হল একটি XML রিসোর্স ফাইল। এর <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 প্রয়োজন এবং গেটার ও সেটার পদ্ধতির সাথে অবজেক্টের মিল থাকতে হবে। গেটার ও সেটারকে অবশ্যই একটি নির্দিষ্ট প্যাটার্নের সাথে মিলতে হবে। যেমন, 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 সম্পর্কে আরও তথ্যের জন্য, নিম্নলিখিত রিসোর্স দেখুন: