MotionLayout
نوعی چیدمان است که به شما کمک میکند پویانمایی ابزاره و حرکت را در برنامهتان مدیریت کنید.
MotionLayout زیرکلاسی از
ConstraintLayout است و بر قابلیتهای غنی چیدمان آن
بنا شده است. بهعنوان بخشی از کتابخانه ConstraintLayout،
MotionLayout بهعنوان کتابخانه پشتیبانی دردسترس است.
MotionLayout فاصله بین انتقالهای چیدمان و مدیریت حرکت پیچیده را پر میکند و ترکیبی از ویژگیها را بین چارچوب پویانمایی ویژگی، TransitionManager، و CoordinatorLayout ارائه میدهد.
علاوهبر توصیف انتقال بین چیدمانها، MotionLayout به شما امکان میدهد
هر ویژگی چیدمانی را پویانمایی کنید. علاوهبراین، این ویژگی ذاتاً از انتقالهای
قابلجستجو پشتیبانی میکند. یعنی میتوانید فوراً هر نقطهای را در گذار براساس شرایطی خاص، مثل ورودی لمسی، نشان دهید. MotionLayout از فریمهای کلیدی نیز پشتیبانی میکند و امکان انتقالهای کاملاً سفارشیشده را برای برآورده کردن نیازهای شما فراهم میکند.
MotionLayout کاملاً توصیفی است، یعنی میتوانید هر انتقالی را در XML توصیف کنید، هرچقدر هم که پیچیده باشد.
ملاحظات طراحی
MotionLayout برای جابهجا کردن، تغییر اندازه، و پویانمایی عناصر میانای کاربر که کاربران با آنها تعامل دارند، مثل دکمهها و نوارهای عنوان، درنظر گرفته شده است. از حرکت در برنامهتان بهعنوان
جلوه ویژه بیدلیل استفاده نکنید. از آن برای کمک به کاربران در درک آنچه برنامهتان انجام میدهد استفاده کنید. برای اطلاعات بیشتر درباره طراحی برنامه با حرکت، بخش «طراحی مواد» درک
حرکت را ببینید.
شروع کنید
برای شروع استفاده از MotionLayout در پروژهتان، این مراحل را دنبال کنید.
-
وابستگی
ConstraintLayoutرا اضافه کنید: برای استفاده ازMotionLayoutدر پروژهتان، وابستگیConstraintLayout2.0 را به فایلbuild.gradleبرنامهتان اضافه کنید. اگر از 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") }
-
ایجاد فایل
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>
-
ایجاد 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 درونیابی میشوند:
alphavisibilityelevationrotation،rotationX،rotationYtranslationX،translationY،translationZscaleX،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> تعریف کنید.
تغییر دادن رنگ پسزمینه
بااستفاده از مثال قبلی، فرض کنید میخواهید رنگهای نما بهعنوان بخشی از حرکت آن تغییر کند، همانطور که در شکل ۲ نشان داده شده است.
یک عنصر <CustomAttribute> به هر عنصر ConstraintSet اضافه کنید، همانطور که در
تکهکد زیر نشان داده شده است:
<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، منابع زیر را ببینید:
- Android پیشرفته در Kotlin 03.2: پویانمایی با MotionLayout
- نمونههای MotionLayout
- نمونههای MotionLayout/ConstraintLayout در GitHub
- مقدمهای بر MotionLayout (بخش اول)
- مقدمهای بر MotionLayout (بخش دوم)
- مقدمهای بر MotionLayout (بخش سوم)
- مقدمهای بر MotionLayout (بخش چهارم)