1. مقدمة
Material Design هو نظام لإنشاء منتجات رقمية جريئة وجميلة. من خلال الجمع بين الأسلوب والعلامة التجارية والتفاعل والحركة ضمن مجموعة متسقة من المبادئ والمكونات، يمكن لفِرق المنتجات تحقيق أقصى إمكانات التصميم.
تساعد مكونات Material Design (MDC) المطوّرين في تنفيذ أسلوب Material Design. يضم مركز MDC، الذي أنشأه فريق من المهندسين ومصممي تجربة المستخدم في Google، عشرات من مكونات واجهة المستخدم الجميلة والعملية، وهو متاح لأجهزة Android وiOS والويب وFlutter.material.io/develop |
ما هو نظام الحركة في Material Design لنظام التشغيل Android؟
نظام Material Motion لنظام Android هو مجموعة من أنماط الانتقال داخل مكتبة MDC-Android التي يمكن أن تساعد المستخدمين في فهم التطبيق والتنقّل خلاله، كما هو موضَّح في إرشادات التصميم المتعدد الأبعاد.
في ما يلي أنماط الانتقال الأربعة الرئيسية في Material:
- تحويل الحاوية: يُستخدم هذا التأثير للانتقال بين عناصر واجهة المستخدم التي تتضمّن حاوية، وينشئ رابطًا مرئيًا بين عنصرَين مختلفَين في واجهة المستخدم من خلال تحويل أحد العنصرَين بسلاسة إلى الآخر.
- المحور المشترك: هو الانتقال بين عناصر واجهة المستخدم التي لها علاقة مكانية أو تنقُّلية، واستخدام التحويل المشترك على المحور "س" أو "ص" أو "ع" لتعزيز العلاقة بين العناصر.
- التلاشي المتسلسل: للانتقال بين عناصر واجهة المستخدم التي لا تربطها علاقة قوية ببعضها البعض، ويتم استخدام تلاشي تسلسلي ويتلاشى للداخل، مع مقياس للعنصر الوارد.
- التلاشي: يُستخدَم مع عناصر واجهة المستخدم التي تدخل في حدود الشاشة أو تخرج منها.
توفّر مكتبة MDC-Android فئات انتقال لهذه الأنماط، وهي مبنية على كلّ من مكتبة AndroidX Transition (androidx.transition
) وإطار عمل Android Transition (android.transition
):
AndroidX
- متوفّر في حزمة
com.google.android.material.transition
- التوافق مع المستوى 14 أو أعلى من واجهة برمجة التطبيقات
- تتيح استخدام المقتطفات وطرق العرض، ولكن ليس الأنشطة أو النوافذ
- يحتوي على إصلاحات أخطاء تم نقلها إلى الإصدارات السابقة وسلوك متّسق على مستوى مستويات واجهة برمجة التطبيقات
إطار العمل
- متوفّر في حزمة
com.google.android.material.transition.platform
- تتوافق مع المستوى 21 من واجهة برمجة التطبيقات أو الإصدارات الأحدث
- تتيح استخدام المقتطفات وعروض الشرائح والأنشطة والنوافذ
- إصلاح الأخطاء التي لم يتم نقلها إلى الإصدار السابق وقد يختلف سلوكها في مختلف مستويات واجهة برمجة التطبيقات
في هذا الدليل التعليمي حول الرموز البرمجية، ستستخدم انتقالات Material المُنشأة على مكتبة AndroidX، ما يعني أنّك ستركز بشكل أساسي على "الأجزاء" و"المشاهد".
ما الذي ستنشئه
سترشدك هذه الدروس التطبيقية حول الترميز خلال عملية إنشاء بعض عمليات النقل إلى نموذج تطبيق بريد إلكتروني Android باسم Reply (رد) باستخدام لغة Kotlin، لتوضيح كيفية استخدام الانتقالات من مكتبة MDC-Android لتخصيص شكل التطبيق ومضمونه.
وسيتم توفير رمز التفعيل لتطبيق Reply، كما ستدمج انتقالات Material التالية في التطبيق، والتي يمكن الاطلاع عليها في ملف GIF للدرس التطبيقي حول الترميز الذي تم إكماله أدناه:
- نقل تحويل الحاوية من قائمة عناوين البريد الإلكتروني إلى صفحة تفاصيل البريد الإلكتروني
- نقل Container Transform من الإجراء إلى الإجراء الرئيسي (FAB) لإنشاء صفحة بريد إلكتروني.
- انتقال المحور ي المشترك من رمز البحث إلى صفحة عرض البحث
- التلاشي خلال الانتقال بين صفحات صندوق البريد
- نقل تحويل الحاوية من شريحة عنوان البريد الإلكتروني إلى طريقة عرض البطاقة
المتطلبات
- معرفة أساسية بتطوير تطبيقات Android ولغة Kotlin
- استوديو Android (يمكنك تنزيله هنا إذا لم يكن لديك)
- محاكي أو جهاز Android (متاح من خلال "استوديو Android")
- نموذج التعليمات البرمجية (راجِع الخطوة التالية)
كيف تقيّم مستوى خبرتك في إنشاء تطبيقات Android؟
2. إعداد بيئة التطوير
تشغيل "استوديو Android"
عند فتح استوديو Android، من المفترض أن تظهر لك نافذة بعنوان "مرحبًا بك في استوديو Android". ومع ذلك، إذا كانت هذه هي المرة الأولى التي تبدأ فيها استخدام Android Studio، اتّبِع خطوات معالج إعداد Android Studio باستخدام القيم التلقائية. قد تستغرق هذه الخطوة عدة دقائق لتنزيل الملفات اللازمة وتثبيتها، لذا يمكنك ترك هذه العملية تعمل في الخلفية أثناء تنفيذ القسم التالي.
الخيار 1: استنساخ تطبيق الدرس التطبيقي للمبتدئين من GitHub
لنسخ الدرس التطبيقي حول الترميز هذا من GitHub، شغِّل الأوامر التالية:
git clone https://github.com/material-components/material-components-android-motion-codelab.git cd material-components-android-motion-codelab
الخيار 2: تنزيل ملف zip لتطبيق بدء دورة تدريبية حول رموز البرمجة
يتوفّر تطبيق إجراء التفعيل ضمن دليل material-components-android-motion-codelab-develop
.
تحميل رمز إجراء التفعيل في "استوديو Android"
- بعد انتهاء معالج الإعداد وظهور نافذة مرحبًا بك في استوديو Android، انقر على فتح مشروع استوديو Android حالي.
- انتقل إلى الدليل الذي قمت فيه بتثبيت نموذج التعليمات البرمجية وحدد نموذج الدليل لفتح المشروع.
- انتظِر قليلاً حتى ينشئ "استوديو Android" المشروع ويزامنه، كما هو موضّح من خلال مؤشرات النشاط أسفل نافذة "استوديو Android".
- في هذه المرحلة، قد يعرض "استوديو Android" بعض أخطاء الإنشاء بسبب عدم توفّر حزمة تطوير البرامج (SDK) لنظام التشغيل Android أو أدوات الإنشاء، مثل الخطأ الموضّح أدناه. اتّبِع التعليمات الواردة في "استوديو Android" لتثبيت هذه العناصر أو تحديثها ومزامنة مشروعك. إذا كنت لا تزال تواجه مشاكل، اتّبِع الدليل حول تحديث أدواتك باستخدام "مدير حِزم تطوير البرامج (SDK)".
التحقّق من تبعيات المشروع
يجب أن يعتمد المشروع على مكتبة MDC-Android. من المفترض أن يحتوي نموذج الرمز البرمجي الذي نزّلته على هذه التبعية، ولكن لنلقي نظرة على الإعدادات للتأكّد من ذلك.
انتقِل إلى ملف build.gradle
الخاص بالوحدة app
وتأكَّد من أنّ القسم dependencies
يتضمّن تبعية لـ MDC-Android:
implementation 'com.google.android.material:material:1.2.0'
تشغيل تطبيق إجراء التفعيل
- تأكَّد من أنّ إعدادات الإصدار على يمين خيار الجهاز هي
app
. - اضغط على زر التشغيل / التشغيل الأخضر لإنشاء التطبيق وتشغيله.
- في نافذة اختيار هدف النشر، إذا كان لديك جهاز Android مُدرَج في الأجهزة المتاحة، انتقِل إلى الخطوة 8. بخلاف ذلك، انقر على إنشاء جهاز افتراضي جديد.
- في شاشة اختيار الأجهزة، اختَر جهاز هاتف، مثل Pixel 3، ثم انقر على التالي.
- في شاشة صورة النظام، اختَر إصدارًا حديثًا من Android، ويُفضَّل أن يكون أعلى مستوى لواجهة برمجة التطبيقات. إذا لم يكن التطبيق مثبّتًا، انقر على رابط تنزيل الذي يظهر وأكمِل عملية التنزيل.
- انقر على التالي.
- في شاشة جهاز Android الظاهري (AVD)، اترك الإعدادات كما هي وانقر على إنهاء.
- اختر جهاز Android من مربّع حوار هدف النشر.
- انقر على حسنًا.
- ينشئ Android Studio التطبيق وينشره ويفتحه تلقائيًا على الجهاز المستهدَف.
اكتمال عملية النقل بنجاح من المفترض أن يتم تشغيل الرمز المبدئي للصفحة الرئيسية في تطبيق Reply في المحاكي. من المفترض أن يظهر لك البريد الوارد الذي يحتوي على قائمة بالرسائل الإلكترونية.
اختياري: إبطاء الصور المتحركة على الجهاز
بما أنّ هذا الدليل التعليمي للترميز يتضمّن انتقالات سريعة ومهذَّبة، قد يكون من المفيد إبطاء الرسوم المتحرّكة على الجهاز من أجل ملاحظة بعض التفاصيل الدقيقة للانتقالات أثناء تنفيذها. ويمكن تنفيذ ذلك باستخدام أوامر adb
shell أو مربّع الإعدادات السريعة. يُرجى العِلم أنّ طُرق إبطاء الرسومات المتحرّكة على الجهاز ستؤثّر أيضًا في الرسومات المتحرّكة على الجهاز خارج تطبيق Reply.
الطريقة 1: أوامر ADB Shell
لإبطاء الصور المتحركة على الجهاز بعامل 10x، يمكنك تشغيل الأوامر التالية من سطر الأوامر:
adb shell settings put global window_animation_scale 10
adb shell settings put global transition_animation_scale 10
adb shell settings put global animator_duration_scale 10
لإعادة ضبط سرعة الصور المتحركة على الجهاز إلى حالتها الطبيعية، شغِّل الأوامر التالية:
adb shell settings put global window_animation_scale 1
adb shell settings put global transition_animation_scale 1
adb shell settings put global animator_duration_scale 1
الطريقة 2: مربّع الإعدادات السريعة
بدلاً من ذلك، لإعداد مربّع "الإعدادات السريعة"، عليك أولاً تفعيل "إعدادات المطوّرين" على جهازك إذا لم يسبق لك إجراء ذلك:
- فتح تطبيق "الإعدادات" على الجهاز
- انتقِل إلى أسفل الصفحة وانقر على "لمحة عن الجهاز المحاكي".
- انتقِل إلى أسفل الصفحة وانقر بسرعة على "رقم الإصدار" إلى أن يتم تفعيل "إعدادات المطوّر".
بعد ذلك، اتّبِع الخطوات التالية، لا تزال ضمن تطبيق "الإعدادات" على الجهاز، لتفعيل مربّع "الإعدادات السريعة":
- انقر على رمز البحث أو شريط البحث في أعلى الشاشة.
- اكتب "مربّعات" في حقل البحث.
- انقر على صف "فئات مطوّري البرامج في الإعدادات السريعة".
- انقر على مفتاح التبديل "حجم الرسوم المتحركة للنافذة".
أخيرًا، خلال الدرس التطبيقي حول الترميز، اسحب مركز إشعارات النظام من أعلى الشاشة واستخدِم رمز للتبديل بين الصور المتحركة ذات السرعة البطيئة والعادية.
3- التعرّف على نموذج رمز التطبيق
لنلقِ نظرة على الرمز. لقد وفّرنا تطبيقًا يستخدم مكتبة مكوِّن التنقل في Jetpack للتنقل بين بعض الأجزاء المختلفة، وكل ذلك ضمن نشاط واحد، وهو MainActivity:
- HomeFragment: لعرض قائمة بالرسائل الإلكترونية
- EmailFragment: يعرض رسالة إلكترونية واحدة كاملة
- ComposeFragment: يتيح إنشاء رسالة إلكترونية جديدة.
- SearchFragment: يعرض طريقة عرض بحث
navigation_graph.xml
أولاً، لفهم طريقة إعداد الرسم البياني للتنقّل في التطبيق، افتح navigation_graph.xml
في دليل app -> src -> main -> res -> navigation
:
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/navigation_graph"
app:startDestination="@id/homeFragment">
<fragment
android:id="@+id/homeFragment"
android:name="com.materialstudies.reply.ui.home.HomeFragment"
android:label="HomeFragment">
<argument...>
<action
android:id="@+id/action_homeFragment_to_emailFragment"
app:destination="@id/emailFragment" />
</fragment>
<fragment
android:id="@+id/emailFragment"
android:name="com.materialstudies.reply.ui.email.EmailFragment"
android:label="EmailFragment">
<argument...>
</fragment>
<fragment
android:id="@+id/composeFragment"
android:name="com.materialstudies.reply.ui.compose.ComposeFragment"
android:label="ComposeFragment">
<argument...>
</fragment>
<fragment
android:id="@+id/searchFragment"
android:name="com.materialstudies.reply.ui.search.SearchFragment"
android:label="SearchFragment" />
<action
android:id="@+id/action_global_homeFragment"
app:destination="@+id/homeFragment"
app:launchSingleTop="true"
app:popUpTo="@+id/navigation_graph"
app:popUpToInclusive="true"/>
<action
android:id="@+id/action_global_composeFragment"
app:destination="@+id/composeFragment" />
<action
android:id="@+id/action_global_searchFragment"
app:destination="@+id/searchFragment" />
</navigation>
لاحظ كيفية توفُّر جميع الأجزاء المذكورة أعلاه، من خلال ضبط جزء التشغيل التلقائي على HomeFragment
من خلال app:startDestination="@id/homeFragment"
. يوفر تعريف XML هذا للرسم البياني لوجهة الأجزاء، بالإضافة إلى الإجراءات، رمز تنقل Kotlin الذي تم إنشاؤه والذي ستواجهه عند ربط عمليات الانتقال.
activity_main.xml
بعد ذلك، اطّلِع على تنسيق activity_main.xml
في الدليل app -> src -> main -> res -> layout
. سيظهر لك الرمز NavHostFragment
الذي تم ضبطه باستخدام الرسم البياني للتنقّل من الأعلى:
<fragment
android:id="@+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:navGraph="@navigation/navigation_graph"/>
يملأ NavHostFragment
الشاشة ويتعامل مع جميع تغييرات التنقل خلال أجزاء ملء الشاشة في التطبيق. ويتم وضع BottomAppBar
وFloatingActionButton
المرتبط بها أيضًا في activity_main.xml
أعلى الجزء الحالي الذي يعرضه NavHostFragment
، وبالتالي سيتم إظهارهما أو إخفاءهما استنادًا إلى وجهة الجزء من خلال نموذج رمز التطبيق المقدَّم.
بالإضافة إلى ذلك، يشير الرمز BottomNavDrawerFragment
في activity_main.xml
إلى درج سفلي يحتوي على قائمة للتنقّل بين صناديق البريد الإلكتروني المختلفة، ويتم عرض هذا الرمز بشكل مشروط من خلال زر شعار BottomAppBar
"الردّ".
MainActivity.kt
وأخيرًا، للاطّلاع على مثال على إجراء تنقُّل قيد الاستخدام، افتح MainActivity.kt
في الدليل app -> src -> main -> java -> com.materialstudies.reply.ui
. حدِّد مكان الدالة navigateToSearch()
التي من المفترض أن تظهر على النحو التالي:
private fun navigateToSearch() {
val directions = SearchFragmentDirections.actionGlobalSearchFragment()
findNavController(R.id.nav_host_fragment).navigate(directions)
}
يوضّح هذا كيفية الانتقال إلى صفحة عرض البحث، بدون أيّ انتقال مخصّص. خلال هذا الدرس التطبيقي حول الترميز، ستتعمق في قسم MainActivity في Reply وأربعة أجزاء رئيسية لإعداد انتقالات Material التي تعمل جنبًا إلى جنب مع إجراءات التنقل المختلفة في جميع أنحاء التطبيق.
والآن بعد أن تعرفت على رمز إجراء التفعيل، لنبدأ في تنفيذ أول عملية انتقال.
4. إضافة انتقال تحويل الحاوية من قائمة عناوين البريد الإلكتروني إلى صفحة تفاصيل البريد الإلكتروني
للبدء، ستضيف انتقالاً عند النقر على رسالة بريد إلكتروني. بالنسبة إلى تغيير التنقّل هذا، يكون نمط تحويل الحاوية مناسبًا تمامًا، لأنّه مصمّم لتأثيرات الانتقال بين عناصر واجهة المستخدم التي تتضمّن حاوية. ينشئ هذا النمط تأثير ربط مرئي بين عنصرَين في واجهة المستخدم.
قبل إضافة أي رمز، حاول تشغيل تطبيق Reply والنقر على رسالة إلكترونية. يجب أن يتم الانتقال سريعًا، أي يتم استبدال الشاشة بدون انتقال:
ابدأ بإضافة سمة transitionName
على MaterialCardView
في email_item_layout.xml
كما هو موضّح في المقتطف التالي:
email_item_layout.xml
android:transitionName="@{@string/email_card_transition_name(email.id)}"
يوجد اسم الانتقال في مورد سلسلة مع معلمة. عليك استخدام معرّف كل رسالة إلكترونية لضمان أنّ كل transitionName
في EmailFragment
فريد.
الآن بعد أن تم تعيين اسم انتقال عنصر قائمة عناوين البريد الإلكتروني، لنفعل الشيء نفسه في تنسيق تفاصيل البريد الإلكتروني. في fragment_email.xml
، اضبط transitionName
من MaterialCardView
على مورد السلسلة التالي:
fragment_email.xml
android:transitionName="@string/email_card_detail_transition_name"
في HomeFragment.kt
، استبدِل الرمز في onEmailClicked
بالمقتطف أدناه لإنشاء عملية الربط من طريقة العرض الأولى (عنصر قائمة البريد الإلكتروني) وطريقة العرض الأخيرة (شاشة تفاصيل البريد الإلكتروني):
HomeFragment.kt
val emailCardDetailTransitionName = getString(R.string.email_card_detail_transition_name)
val extras = FragmentNavigatorExtras(cardView to emailCardDetailTransitionName)
val directions = HomeFragmentDirections.actionHomeFragmentToEmailFragment(email.id)
findNavController().navigate(directions, extras)
بعد ضبط الربط، يمكنك إنشاء عملية تحويل حاوية. في طريقة EmailFragment
onCreate
، اضبط sharedElementEnterTransition
على مثيل جديد من MaterialContainerTransform
(استيراد إصدار com.google.android.material.transition
بدلاً من إصدار com.google.android.material.transition.platform
) عن طريق إضافة المقتطف التالي:
EmailFragment.kt
sharedElementEnterTransition = MaterialContainerTransform().apply {
drawingViewId = R.id.nav_host_fragment
duration = resources.getInteger(R.integer.reply_motion_duration_large).toLong()
scrimColor = Color.TRANSPARENT
setAllContainerColors(requireContext().themeColor(R.attr.colorSurface))
}
يمكنك الآن إعادة تشغيل التطبيق.
بدأت الأمور تبدو رائعة. عند النقر على رسالة إلكترونية في قائمة عناوين البريد الإلكتروني، من المفترض أن يؤدي تحويل الحاوية إلى توسيع عنصر القائمة إلى صفحة تفاصيل بملء الشاشة. ومع ذلك، لاحظ أنّ الضغط على "رجوع" لا يؤدي إلى تصغير الرسالة الإلكترونية مرة أخرى في القائمة. بالإضافة إلى ذلك، تختفي قائمة عناوين البريد الإلكتروني فورًا في بداية عملية النقل، ويتم عرض خلفية النافذة الرمادية. لم ننتهي بعد.
لإصلاح انتقال الإرجاع، أضِف السطرين التاليين إلى طريقة onViewCreated
في HomeFragment.kt
:
HomeFragment.kt
postponeEnterTransition()
view.doOnPreDraw { startPostponedEnterTransition() }
حاوِل إعادة تشغيل التطبيق. سيؤدي الضغط على "رجوع" بعد فتح رسالة إلكترونية إلى تصغير الرسالة الإلكترونية مرة أخرى في القائمة. أحسنت. لنواصل تحسين الصورة المتحركة.
مشكلة اختفاء قائمة عناوين البريد الإلكتروني هي أنه عند الانتقال إلى جزء جديد باستخدام مكوِّن التنقل، تتم إزالة الجزء الحالي على الفور واستبداله بالجزء الوارد الجديد. لإبقاء قائمة عناوين البريد الإلكتروني مرئية حتى بعد استبدالها، يمكنك إضافة انتقال خروج إلى HomeFragment
.
أضِف المقتطف أدناه إلى طريقة HomeFragment
onEmailClicked
لتوسيع قائمة الرسائل الإلكترونية بشكلٍ دقيق عند الخروج والعودة مرة أخرى عند إعادة الدخول:
HomeFragment.kt
exitTransition = MaterialElevationScale(false).apply {
duration = resources.getInteger(R.integer.reply_motion_duration_large).toLong()
}
reenterTransition = MaterialElevationScale(true).apply {
duration = resources.getInteger(R.integer.reply_motion_duration_large).toLong()
}
بعد ذلك، لضمان تطبيق انتقال MaterialElevationScale
على الشاشة الرئيسية ككل، بدلاً من كل عرض فردي في التسلسل الهرمي، ضَع علامة على RecyclerView
في fragment_home.xml
كمجموعة انتقال.
fragment_home.xml
android:transitionGroup="true"
في هذه المرحلة، يُفترض أن يكون لديك تحويل حاوية يعمل بكامل طاقته. يؤدي النقر على رسالة إلكترونية إلى توسيع عنصر القائمة في شاشة التفاصيل مع طي قائمة الرسائل الإلكترونية. يؤدي الضغط على زر الرجوع إلى تصغير شاشة تفاصيل البريد الإلكتروني مرة أخرى إلى عنصر قائمة مع زيادة حجم قائمة رسائل البريد الإلكتروني.
5- إضافة انتقال تحويل الحاوية من التطبيق المصغّر في الشريط الجانبي إلى صفحة كتابة الرسالة الإلكترونية
لنواصل تحويل الحاوية ونضيف انتقالًا من زر الإجراء العائم إلى ComposeFragment
، مع توسيع زر الإجراء العائم إلى رسالة إلكترونية جديدة ليكتبها المستخدم. أولاً، أعد تشغيل التطبيق وانقر على زر الإجراء الرئيسي (FAB) للتأكد من عدم وجود انتقال عند تشغيل شاشة إنشاء الرسالة الإلكترونية.
على الرغم من أنّنا نستخدم فئة الانتقال نفسها، ستكون طريقة ضبط هذه النسخة مختلفة لأنّ عنصر FAB مضمّن في MainActivity
ويتم وضع ComposeFragment
داخل حاوية مضيف التنقّل MainActivity
.
في ComposeFragment.kt
، أضِف المقتطف التالي إلى طريقة onViewCreated
، مع الحرص على استيراد إصدار androidx.transition
من Slide
.
ComposeFragment.kt
enterTransition = MaterialContainerTransform().apply {
startView = requireActivity().findViewById(R.id.fab)
endView = emailCardView
duration = resources.getInteger(R.integer.reply_motion_duration_large).toLong()
scrimColor = Color.TRANSPARENT
containerColor = requireContext().themeColor(R.attr.colorSurface)
startContainerColor = requireContext().themeColor(R.attr.colorSecondary)
endContainerColor = requireContext().themeColor(R.attr.colorSurface)
}
returnTransition = Slide().apply {
duration = resources.getInteger(R.integer.reply_motion_duration_medium).toLong()
addTarget(R.id.email_card_view)
}
بالإضافة إلى المَعلمات المستخدَمة في عملية تحويل الحاوية السابقة، يتم ضبط startView
وendView
يدويًا هنا. بدلاً من استخدام سمات transitionName
لإعلام نظام انتقالات Android بعناصر العرض التي يجب تحويلها، يمكنك تحديدها يدويًا عند الضرورة.
بعد ذلك، أعِد تشغيل التطبيق. ويُفترض أن يظهر لك زر الإجراء الرئيسي وهو يتحول إلى شاشة الإنشاء (يمكنك الاطّلاع على ملف GIF في نهاية هذه الخطوة).
كما هي الحال في الخطوة السابقة، يجب إضافة تأثير انتقال إلى HomeFragment
لمنعه من الاختفاء بعد إزالته واستبداله بـ ComposeFragment
.
انسخ المقتطف أدناه في طريقة navigateToCompose
في MainActivity
قبل طلب NavController
navigate
.
MainActivity.kt
currentNavigationFragment?.apply {
exitTransition = MaterialElevationScale(false).apply {
duration = resources.getInteger(R.integer.reply_motion_duration_large).toLong()
}
reenterTransition = MaterialElevationScale(true).apply {
duration = resources.getInteger(R.integer.reply_motion_duration_large).toLong()
}
}
لقد انتهينا من هذه الخطوة. من المفترض أن يظهر لك انتقال من زر التطبيق المصغّر للإجراءات السريعة إلى شاشة الإنشاء على النحو التالي:
6- إضافة تأثير محور ي مشترَك من رمز البحث إلى صفحة عرض البحث
في هذه الخطوة، سنضيف انتقالًا من رمز البحث إلى عرض البحث بملء الشاشة. بما أنّه لا تتضمّن عملية التنقّل هذه حاوية دائمة، يمكننا استخدام انتقال مشترَك على محور "ع" لتعزيز العلاقة المكانية بين الشاشتَين والإشارة إلى الانتقال إلى مستوى أعلى في التسلسل الهرمي للتطبيق.
قبل إضافة أي رمز إضافي، جرِّب تشغيل التطبيق والنقر على رمز البحث في أسفل يسار الشاشة. من المفترض أن يؤدي هذا إلى إظهار شاشة عرض البحث بدون انتقال.
للبدء، ابحث عن طريقة navigateToSearch
في MainActivity
، وأضِف مقتطف الرمز البرمجي التالي قبل طلب طريقة NavController
navigate
لإعداد عملية الخروج من المقتطف الحالي وإعادة الدخول إلى عمليات النقل MaterialSharedAxis
على محور Z.
MainActivity.kt
currentNavigationFragment?.apply {
exitTransition = MaterialSharedAxis(MaterialSharedAxis.Z, true).apply {
duration = resources.getInteger(R.integer.reply_motion_duration_large).toLong()
}
reenterTransition = MaterialSharedAxis(MaterialSharedAxis.Z, false).apply {
duration = resources.getInteger(R.integer.reply_motion_duration_large).toLong()
}
}
بعد ذلك، أضِف مقتطف الرمز التالي إلى طريقة onCreate
في SearchFragment
، الذي يضبط انتقالات MaterialSharedAxis
للدخول والرجوع.
SearchFragment.kt
enterTransition = MaterialSharedAxis(MaterialSharedAxis.Z, true).apply {
duration = resources.getInteger(R.integer.reply_motion_duration_large).toLong()
}
returnTransition = MaterialSharedAxis(MaterialSharedAxis.Z, false).apply {
duration = resources.getInteger(R.integer.reply_motion_duration_large).toLong()
}
أخيرًا، لضمان تطبيق انتقال MaterialSharedAxis
على شاشة البحث ككل، بدلاً من وضع علامة على LinearLayout
في fragment_search.xml
كمجموعة انتقالية، بدلاً من كل طريقة عرض فردية في التسلسل الهرمي.
fragment_search.xml
android:transitionGroup="true"
هذا كل شيء! حاول الآن إعادة تشغيل التطبيق والنقر على أيقونة البحث. يجب أن تتلاشى شاشتا العرض الرئيسي وعرض البحث في الوقت نفسه وتتزايدان على طول محور Z في العمق، ما يخلق تأثيرًا سلسًا بين الشاشتَين.
7- إضافة تأثير التلاشي خلال الانتقال بين صفحات صندوق البريد
في هذه الخطوة، سنضيف انتقالًا بين صناديق البريد الإلكتروني المختلفة. بما أنّنا لا نريد التأكيد على علاقة مكانية أو هرمية، سنستخدم تمويهًا لإجراء "تبديل" بسيط بين قوائم الرسائل الإلكترونية.
قبل إضافة أي رمز إضافي، جرِّب تشغيل التطبيق والنقر على شعار الرد في شريط التطبيقات السفلي وتبديل بريد البريد الإلكتروني. من المفترض أن تتغيّر قائمة الرسائل الإلكترونية بدون أي عملية انتقال.
للبدء، ابحث عن طريقة navigateToHome
في MainActivity
، وأضِف مقتطف الرمز التالي قبل طلب طريقة NavController
navigate
لإعداد انتقال MaterialFadeThrough
للخروج من المقتطف الحالي.
MainActivity.kt
currentNavigationFragment?.apply {
exitTransition = MaterialFadeThrough().apply {
duration = resources.getInteger(R.integer.reply_motion_duration_large).toLong()
}
}
بعد ذلك، افتح HomeFragment
. في onCreate
، اضبط السمة enterTransition
للجزء على مثيل جديد من MaterialFadeThrough
.
HomeFragment.kt
enterTransition = MaterialFadeThrough().apply {
duration = resources.getInteger(R.integer.reply_motion_duration_large).toLong()
}
أعِد تشغيل التطبيق. عند فتح مربّع التنقل السفلي وتغيير بريد البريد الإلكتروني، من المفترض أن تتلاشى القائمة الحالية للرسائل الإلكترونية وتتوسّع، بينما تتلاشى القائمة الجديدة وتتوسّع. أحسنت.
8. إضافة نقل Container Transform (تحويل الحاوية) من شريحة عنوان البريد الإلكتروني إلى طريقة عرض البطاقة
في هذه الخطوة، ستضيف انتقالًا يحوّل شريحة إلى بطاقة منبثقة. يُستخدم تحويل الحاوية هنا للمساعدة في إبلاغ المستخدم بأنّ الإجراء المتخذ في النافذة المنبثقة سيؤثر في الشريحة التي نشأت منها النافذة المنبثقة.
قبل إضافة أي رمز، شغِّل تطبيق Reply وانقر على رسالة إلكترونية، ثم انقر على زر "الرد" المصغّر للتفاعل السريع، ثم حاوِل النقر على شريحة جهة اتصال المستلِم. من المفترض أن تختفي الشريحة على الفور وأن تظهر بطاقة تتضمّن عناوين البريد الإلكتروني لجهة الاتصال هذه بدون أي صور متحركة.
وستعمل باللغة ComposeFragment
في هذه الخطوة. سبق أن تمت إضافة شرائح المستلِمين (مرئية تلقائيًا) وبطاقة مستلِم (غير مرئية تلقائيًا) في التنسيق ComposeFragment
. شريحة المستلِم وهذه البطاقة هما طريقتا العرض الذي سيتم تحويل حاوية بينهما.
للبدء، افتح ComposeFragment
وابحث عن طريقة expandChip
. يتمّ استدعاء هذه الطريقة عند النقر على chip
المقدَّمة. أضِف مقتطف الرمز التالي فوق السطور التي تبدِّل مستوى الرؤية recipientCardView
وchip
، ما سيؤدي إلى تشغيل عملية تحويل الحاوية المسجَّلة عبر beginDelayedTransition
.
ComposeFragment.kt
val transform = MaterialContainerTransform().apply {
startView = chip
endView = binding.recipientCardView
scrimColor = Color.TRANSPARENT
endElevation = requireContext().resources.getDimension(
R.dimen.email_recipient_card_popup_elevation_compat
)
addTarget(binding.recipientCardView)
}
TransitionManager.beginDelayedTransition(binding.composeConstraintLayout, transform)
إذا شغّلت التطبيق الآن، من المفترض أن تتحول الشريحة إلى بطاقة تتضمّن عناوين البريد الإلكتروني للمستلِم. بعد ذلك، لنضبط انتقال الإرجاع لتصغير البطاقة إلى الشريحة مرة أخرى.
في الطريقة collapseChip
في ComposeFragment
، أضِف مقتطف الرمز البرمجي أدناه لتصغير البطاقة مرة أخرى إلى الشريحة.
ComposeFragment.kt
val transform = MaterialContainerTransform().apply {
startView = binding.recipientCardView
endView = chip
scrimColor = Color.TRANSPARENT
startElevation = requireContext().resources.getDimension(
R.dimen.email_recipient_card_popup_elevation_compat
)
addTarget(chip)
}
TransitionManager.beginDelayedTransition(binding.composeConstraintLayout, transform)
يُرجى إعادة تشغيل التطبيق. من المفترض أن يؤدي النقر على الشريحة إلى توسيع الشريحة لتصبح بطاقة، بينما يؤدي النقر على البطاقة إلى تصغيرها مرة أخرى لتصبح شريحة. أحسنت.
9. تم
باستخدام أقل من 100 سطر من رمز Kotlin وبعض علامات XML الأساسية، ساعدتك مكتبة MDC-Android في إنشاء انتقالات جميلة في تطبيق حالي يتوافق مع إرشادات Material Design، ويبدو أيضًا أنّه يعمل بشكلٍ متسق على جميع أجهزة Android.
الخطوات التالية
لمزيد من المعلومات حول نظام الحركة في واجهة Material، احرص على الاطّلاع على المواصفات ومستندات المطوّرين الكاملة، وجرِّب إضافة بعض الانتقالات في واجهة Material إلى تطبيقك.
نشكرك على تجربة Material motion. نأمل أنّك استفدت من هذا الدرس التطبيقي حول الترميز.