MotionLayout
هو نوع تنسيق يساعدك في إدارة الحركة والرسوم المتحركة للعناصر في تطبيقك.
MotionLayout هو فئة فرعية من
ConstraintLayout ويستند إلى إمكانات التنسيق الغنية. كجزء من مكتبة ConstraintLayout، يتوفّر MotionLayout كمكتبة دعم.
MotionLayout يسدّ الفجوة بين عمليات نقل التنسيق ومعالجة الحركة المعقّدة، ويقدّم مزيجًا من الميزات بين إطار عمل الرسوم المتحركة للسمات وTransitionManager وCoordinatorLayout.
بالإضافة إلى وصف عمليات النقل بين التنسيقات، يتيح لك MotionLayout تحريك أي سمات تنسيق. علاوةً على ذلك، فهو يتيح بشكلٍ أساسي عمليات النقل القابلة للبحث. وهذا يعني أنّه يمكنك على الفور عرض أي نقطة ضمن عملية النقل استنادًا إلى شرط معيّن، مثل إدخال اللمس. يتيح MotionLayout أيضًا الإطارات الرئيسية، ما يتيح عمليات نقل مخصّصة بالكامل لتلبية احتياجاتك.
MotionLayout تعريفية بالكامل، ما يعني أنّه يمكنك وصف أي عمليات نقل بتنسيق XML، بغض النظر عن مدى تعقيدها.
اعتبارات التصميم
يهدف MotionLayout إلى نقل عناصر واجهة المستخدم التي يتفاعل معها المستخدمون وتغيير حجمها وتحريكها، مثل الأزرار وأشرطة العناوين. لا تستخدم الحركة في تطبيقك كتأثير خاص مجاني. استخدِمها لمساعدة المستخدمين في فهم ما يفعله تطبيقك. لمزيد من المعلومات عن تصميم تطبيقك باستخدام الحركة، يُرجى الاطّلاع على قسم فهم
الحركة في
التصميم المتعدد الأبعاد.
البدء
اتّبِع الخطوات التالية لبدء استخدام MotionLayout في مشروعك.
-
أضِف الاعتمادية
ConstraintLayout: لاستخدامMotionLayoutفي مشروعك، أضِف الاعتماديةConstraintLayout2.0 إلى ملفbuild.gradleالخاص بتطبيقك. إذا كنت تستخدم AndroidX، أضِف التبعية التالية:Groovy
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") }
-
أنشِئ ملف
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 .../>
في ما يلي مثال كامل لمل0/ف
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:
alphavisibilityelevationrotation،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 (الجزء الرابع)