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