MotionLayout
هو نوع تنسيق يساعدك في إدارة الحركة والصور المتحركة للأداة في تطبيقك.
MotionLayout
هو فئة فرعية من
ConstraintLayout
ويستند إلى إمكانات
التنسيق الغني. كجزء من مكتبة ConstraintLayout
، يمكن استخدام
MotionLayout
كمكتبة دعم.
يعمل MotionLayout
على سدّ الفجوة بين انتقالات التصميم والتعامل مع الحركة المعقّدة،
ما يوفّر مزيجًا من الميزات بين إطار عمل الصور المتحركة
للمواقع
وTransitionManager
و
CoordinatorLayout
.
بالإضافة إلى وصف الانتقالات بين التنسيقات، يتيح لك MotionLayout
إضافة تأثيرات حركية إلى أي خصائص تنسيق. علاوةً على ذلك، تدعم بطبيعتها عمليات النقل
المطلوبة. هذا يعني أنه يمكنك إظهار أي نقطة داخل الانتقال فورًا
بناءً على حالة ما، مثل الإدخال باللمس. يتيح MotionLayout
أيضًا استخدام الإطارات الرئيسية، ما يتيح عمليات انتقال مخصّصة بالكامل تناسب احتياجاتك.
MotionLayout
هو مصطلح معبّر تمامًا، ما يعني أنّه يمكنك وصف أي عمليات انتقال في XML مهما كانت معقدة.
اعتبارات التصميم
MotionLayout
مخصص لنقل عناصر واجهة المستخدم وتغيير حجمها وتحريكها التي يتفاعل معها المستخدمون، مثل الأزرار وأشرطة العناوين. لا تستخدم الحركة في تطبيقك
كتأثير خاص غير مبرر. استخدمها لمساعدة المستخدمين
في فهم وظيفة تطبيقك. لمزيد من المعلومات حول تصميم تطبيقك باستخدام الحركة، راجع قسم "التصميم المتعدد الأبعاد" فهم الحركة.
البدء
اتّبِع هذه الخطوات لبدء استخدام "MotionLayout
" في مشروعك.
-
إضافة التبعية
ConstraintLayout
: لاستخدامMotionLayout
في مشروعك، أضِف تبعيةConstraintLayout
2.0 إلى ملفbuild.gradle
لتطبيقك. إذا كنت تستخدم AndroidX، أضِف التبعية التالية:رائع
dependencies { implementation "androidx.constraintlayout:constraintlayout:2.2.0-alpha13" // To use constraintlayout in compose implementation "androidx.constraintlayout:constraintlayout-compose:1.1.0-alpha13" }
Kotlin
dependencies { implementation("androidx.constraintlayout:constraintlayout:2.2.0-alpha13") // To use constraintlayout in compose implementation("androidx.constraintlayout:constraintlayout-compose:1.1.0-alpha13") }
-
إنشاء ملف
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
يحدّد التنسيق الموضّح في الشكل 1: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
.في ما يلي مثال على ملف مشهد للحركة يصف الحركة الأفقية الأساسية في الشكل 1:
<?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. يجب أن تتطابق قيم getter وsetter مع نمط معيّن. على سبيل المثال، يمكن استخدامbackgroundColor
لأن العرض يتضمن طريقتينgetBackgroundColor()
وsetBackgroundColor()
أساسيتين. - تستند السمة الأخرى التي يجب تقديمها إلى نوع القيمة. اختَر من بين الأنواع المتوافقة التالية:
motion:customColorValue
للألوانmotion:customIntegerValue
للأعداد الصحيحةmotion:customFloatValue
للأعداد العشريةmotion:customStringValue
للسلاسلmotion:customDimension
للسماتmotion:customBoolean
للقيم المنطقية
عند تحديد سمة مخصّصة، عليك تحديد قيم نقطة النهاية في عنصرَي <ConstraintSet>
للبداية والنهاية.
تغيير لون الخلفية
بناءً على المثال السابق، افترض أنك تريد تغيير ألوان العرض كجزء من حركته، كما هو موضح في الشكل 2.
أضِف عنصر <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 (الجزء الرابع)