نقل واجهة المستخدم إلى التنسيقات المتجاوبة

تحتاج تطبيقات Android إلى دعم منظومة متكاملة آخذة في التزايد من أشكال الأجهزة. يجب أن تستجيب واجهة المستخدم للتطبيق لتناسب مجموعة واسعة من أحجام الشاشات بالإضافة إلى الاتجاهات وحالات الجهاز المختلفة.

تركز واجهة المستخدم سريعة الاستجابة على مبادئ المرونة والاستمرارية.

تشير المرونة إلى التنسيقات التي تستفيد على أفضل نحو من المساحة المتاحة وتعدّلها عند تغيير المساحة المتاحة. يمكن أن تتخذ التعديلات أشكالاً متعددة: مجرد زيادة حجم عرض واحد، وإعادة ضبط موضع طرق العرض بحيث يمكن الوصول إليها في مواقع أكثر سهولة، أو إظهار أو إخفاء مشاهدات إضافية، أو مزيج من هذا.

تشير الاستمرارية إلى التمتع بتجربة مستخدم سلسة أثناء الانتقال من حجم نافذة إلى آخر. مهما كانت التجربة التي يشارك فيها المستخدم يجب أن تستمر دون انقطاع. نظرًا لأن التغيير في الحجم قد يصاحبه تدمير وإعادة إنشاء التسلسل الهرمي لطريقة العرض بالكامل، فمن المهم ألا يفقد المستخدم مكانه أو بياناته.

أمور يجب تجنّبها

تجنَّب استخدام القيم المادية للأجهزة لاتخاذ قرارات بشأن التصميم. قد يكون من المغري اتخاذ قرارات بناءً على قيمة ثابتة، ولكن في كثير من الحالات لا تكون هذه القيم مفيدة لتحديد المساحة التي يمكن أن تعمل بها واجهة المستخدم.

على الأجهزة اللوحية، قد يتم تشغيل تطبيق في وضع النوافذ المتعددة، ما يعني أنّ التطبيق يشارك الشاشة مع تطبيق آخر. في نظام التشغيل ChromeOS، قد يكون التطبيق في نافذة يمكن تغيير حجمها. يمكن أن يكون هناك أكثر من شاشة مادية واحدة، مثل جهاز قابل للطي أو جهاز به شاشات متعددة. في كل هذه الحالات، لا يكون حجم الشاشة الفعلي ذا صلة بتحديد كيفية عرض المحتوى.

أجهزة متعددة تعرض نوافذ تطبيقات بأحجام مختلفة.
الشكل 1. يمكن أن تختلف أحجام النوافذ عن حجم الجهاز أو الشاشة.

وللسبب ذاته، تجنَّب قفل التطبيق باتجاهات أو نسبة عرض إلى ارتفاع معيّنة. على الرغم من أن الجهاز نفسه قد يكون في اتجاه معين، إلا أنّ اتجاه التطبيق قد يكون مختلفًا استنادًا إلى حجم نافذته فقط. على سبيل المثال، على جهاز لوحي في وضع أفقي أثناء استخدام وضع النوافذ المتعددة، يمكن أن يكون التطبيق في الوضع العمودي لأنه أطول من عرضه.

وتجنَّب أيضًا محاولة تحديد ما إذا كان الجهاز هاتفًا أو جهازًا لوحيًا. ما الذي يؤهّلك بشكل خاص كجهاز لوحي هو أمر شخصي إلى حد ما: هل يعتمد على حجم معين، أو نسبة عرض إلى ارتفاع، أو مزيج من الحجم ونسبة العرض إلى الارتفاع؟ مع ظهور أشكال جديدة، يمكن أن تتغير هذه الافتراضات، ويفقد التمييز أهمية.

بدلاً من تجربة أي من الاستراتيجيات السابقة، استخدم نقاط التوقف وفئات حجم النافذة.

فئات نقاط التوقف وحجم النوافذ

الجزء الفعلي من الشاشة الذي تم تخصيصه لتطبيقك هو نافذة التطبيق. قد يشغل هذا القسم ملء الشاشة أو جزءًا من الشاشة، لذا استخدِم حجم النافذة عند اتخاذ قرارات عالية المستوى بشأن تصميم التطبيق.

عند التصميم لعوامل شكل متعددة، ابحث عن قيم الحدود حيث تتفرع هذه القرارات عالية المستوى في اتجاهات مختلفة. وتحقيقًا لهذه الغاية، توفر شبكة التخطيط المتجاوبة في Material Design نقاط توقف للعرض والارتفاع، ما يتيح لك تعيين الأحجام الأولية في مجموعات منفصلة وموحدة يشار إليها باسم فئات حجم النافذة. نظرًا لانتشار التمرير العمودي في كل مكان، تهتم معظم التطبيقات بشكل أساسي بفئات حجم العرض، لذلك يمكن تحسين معظم التطبيقات لتتوافق مع جميع أحجام الشاشات من خلال معالجة بضع نقاط توقف فقط. (لمزيد من المعلومات عن فئات حجم النوافذ، يُرجى الاطّلاع على فئات حجم النافذة.)

عناصر واجهة المستخدم الثابتة

تحدد إرشادات التخطيط للتصميم المتعدد الأبعاد مناطق أشرطة التطبيقات والتنقل والمحتوى. عادةً ما يكون العنصران الأولان هما عناصر ثابتة لواجهة المستخدم في (أو قريبًا جدًا) من جذر العرض الهرمي. يُرجى العلم أنّ عبارة "مستمرة" لا تعني بالضرورة أنّ العرض سيكون مرئيًا دائمًا، بل يعني أنّه سيبقى في مكانه بينما قد يتم نقل أو تغيير طرق عرض أخرى للمحتوى. على سبيل المثال، يمكن أن يكون عنصر التنقل في درج متحرك خارج الشاشة، لكن الدرج دائمًا هناك.

يمكن للعناصر الثابتة أن تستجيب، وعادة ما تستخدم إما العرض الكامل أو الارتفاع الكامل للنافذة، لذلك يُفضل استخدام فئات الحجم لتحديد مكان وضعها. يوضح هذا المساحة المتبقية للمحتوى. في المقتطف التالي، يستخدم النشاط شريطًا سفليًا للشاشات المكثفة وشريطًا علويًا للشاشات الأكبر حجمًا. تستخدم التخطيطات المؤهلة نقاط توقف العرض كما هو موضح سابقًا.

<!-- res/layout/main_activity.xml -->

<androidx.constraintlayout.widget.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <!-- content view(s) -->

    <com.google.android.material.bottomappbar.BottomAppBar
        android:layout_width="wrap_content"
        android:layout_height="0dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        ... />
</androidx.constraintlayout.widget.ConstraintLayout>


<!-- res/layout-w600dp/main_activity.xml -->
<androidx.constraintlayout.widget.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.google.android.material.appbar.AppBarLayout
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        ... />

    <!-- content view(s) -->
</androidx.constraintlayout.widget.ConstraintLayout>

المحتوى

بعد تحديد موضع عناصر واجهة المستخدم الثابتة، استخدِم المساحة المتبقية للمحتوى، مثلاً باستخدام NavHostFragment مع الرسم البياني للتنقّل في تطبيقك. راجع التنقل لواجهات المستخدم سريعة الاستجابة لمعرفة اعتبارات إضافية.

التأكد من توفر كل البيانات لأحجام مختلفة

تستخدم معظم أطر التطبيقات اليوم نموذج بيانات منفصل عن مكونات Android التي تساهم في واجهة المستخدم (الأنشطة والشرائح وطرق العرض). باستخدام Jetpack، يتم عادةً تنفيذ هذا الدور من خلال ViewModels، والتي لها فائدة إضافية تتمثل في الحفاظ على التغييرات في الإعدادات (يمكنك الاطّلاع على نظرة عامة على ViewModel للحصول على مزيد من المعلومات).

عند تنفيذ تخطيط يتكيف مع الأحجام المختلفة، قد يكون من المغري استخدام نموذج بيانات مختلف بناءً على الحجم الحالي. ومع ذلك، هذا يتعارض مع مبدأ تدفق البيانات أحادي الاتجاه. يجب أن تتدفق البيانات لأسفل إلى المشاهدات، ويجب أن تتدفق أحداث مثل تفاعلات المستخدم إلى أعلى. يؤدي إنشاء تبعية في الاتجاه الآخر، حيث يعتمد نموذج البيانات على تكوين طبقة واجهة المستخدم، إلى تعقيد ذلك بشكل كبير. عندما يتغير حجم التطبيق، يجب عليك حينئذٍ مراعاة التحويل من نموذج بيانات إلى آخر.

بدلاً من ذلك، اسمح لنموذج البيانات الخاص بك باستيعاب أكبر فئة حجم، وبعد ذلك يمكنك عرض المحتوى أو إخفاؤه أو إعادة موضعه بشكل انتقائي في واجهة المستخدم للتكيّف مع فئة الحجم الحالية. في ما يلي بعض الاستراتيجيات التي يمكنك استخدامها عند تحديد سلوك التخطيط عند الانتقال بين فئات المقاسات.

توسيع المحتوى

التنسيقات الأساسية: الخلاصة

يمكن أن تكون المساحة الموسعة فرصة لجعل الأشياء أكبر وإعادة تنسيق المحتوى بحيث يسهل الوصول إليه.

تكبير المجموعات: يعرض العديد من التطبيقات مجموعة من العناصر في حاوية يمكن التنقّل فيها، مثل RecyclerView أو ScrollView. إن تمكين حاوية لتصبح أكبر تلقائيًا يعني إمكانية عرض المزيد من المحتوى. ومع ذلك، يُرجى الحرص على ألّا يتوسّع المحتوى داخل الحاوية أو يشوّهه بشكل مفرط. على سبيل المثال، باستخدام RecyclerView، يمكنك استخدام أداة إدارة تنسيق مختلفة، مثل GridLayoutManager أوStaggeredGridLayoutManager أو FlexboxLayout عندما لا يكون العرض مكثّفًا.

جهاز مطوي وغير مطوي يوضح كيف يحدد مدراء التنسيق المختلفون التطبيق بشكل مختلف بناءً على فئة حجم العرض.
الشكل 2. مديرو تنسيق مختلف لفئات أحجام النوافذ المختلفة.

يمكن للعناصر الفردية أيضًا استخدام حجم أو شكل مختلف لعرض المزيد من المحتوى وتمييز حدود العناصر بسهولة أكبر.

ركِّز على عنصر رئيسي: إذا كان التخطيط يحتوي على نقطة محورية معينة، مثل صورة أو فيديو، فقم بتوسيعه عند نمو نافذة التطبيق للحفاظ على انتباه المستخدم. يمكن إعادة ترتيب العناصر الداعمة الأخرى حول عرض الجزء الرئيسي أو أسفله.

تتوفر طرق عديدة لإنشاء مثل هذا التنسيق، إلّا أنّ السمة ConstraintLayout مناسبة بشكل خاص لهذا الغرض لأنّها توفّر العديد من الطرق لتضييق نطاق العرض الفرعي، بما في ذلك النسبة المئوية أو فرض نسبة العرض إلى الارتفاع ووضع عناصرها الثانوية بالنسبة إلى نفسها أو بأطفال آخرين. اطّلِع على المزيد من المعلومات عن كل هذه الإمكانات في مقالة إنشاء واجهة مستخدم سريعة الاستجابة باستخدام ConstraintLayout.

عرض المحتوى القابل للتصغير تلقائيًا في حال توفّر مساحة، اعرض المحتوى الذي لا يمكن الوصول إليه إلا من خلال تفاعل إضافي من المستخدم مثل النقر أو التمرير أو الإيماءات. على سبيل المثال، المحتوى الذي يظهر في واجهة ذات علامات تبويب عند ضغطه يمكن بدلاً من ذلك إعادة ترتيبه في أعمدة أو قائمة عند توفر مساحة أكبر.

توسيع الهوامش إذا كانت المساحة كبيرة جدًا بحيث لا يمكنك العثور على ملاءمة جذابة حتى بعد استخدام كل المحتوى الخاص بك، فقم بتوسيع هوامش التنسيق بحيث يظل المحتوى في الوسط وتكون طرق العرض الفردية ذات أحجام طبيعية ومسافات بينها.

بدلاً من ذلك، يمكن تحويل مكون بملء الشاشة إلى واجهة مستخدم لمربع حوار عائم. يكون هذا مناسبًا بشكل خاص عندما يتطلب هذا المكون تركيزًا حصريًا لإنجاز مهمة مستخدم فورية، مثل إنشاء رسالة بريد إلكتروني أو إنشاء حدث تقويم.

هاتف عادي يعرض مربّع حوار بملء الشاشة وهاتفًا قابلاً للطي غير مطوي يعرض مربّع الحوار نفسه كنافذة عائمة
الشكل 3. تم تحويل مربّع حوار ملء الشاشة إلى مربّع حوار عادي بعرض متوسط وموسَّع.

إضافة محتوى

التنسيقات الأساسية: جزء الدعم، وعرض تفاصيل القائمة

استخدِم لوحة داعمة. تعرض لوحة الدعم محتوى إضافيًا أو إجراءات سياقية ذات صلة بالمحتوى الأساسي، مثل التعليقات في مستند ما أو العناصر في قائمة التشغيل. عادةً ما تستخدم هذه الثلث السفلي من الشاشة للارتفاع الموسع أو الثلث اللاحق للعرض الموسع.

أحد الاعتبارات المهمة هو مكان وضع هذا المحتوى عندما لا تكون هناك مساحة كافية لإظهار الجزء. في ما يلي بعض البدائل التي يمكنك استكشافها:

  • الدرج الجانبي عند حافة اللاحقة باستخدام DrawerLayout
  • الدرج السفلي باستخدام BottomSheetBehavior
  • يمكن الوصول إلى القائمة أو النافذة المنبثقة بالنقر على رمز القائمة
الشكل 4. الطرق البديلة لعرض محتوى إضافي في اللوحة الداعمة.

أنشئ تنسيقًا من لوحتين. قد تعرض الشاشات الكبيرة مجموعة من الميزات التي تظهر عادةً بشكل منفصل على الشاشات الأصغر. أحد أنماط التفاعل الشائعة في العديد من التطبيقات هو عرض قائمة بالعناصر، مثل جهات الاتصال أو نتائج البحث، والتبديل إلى تفاصيل عنصر ما عند تحديد العنصر. بدلاً من تكبير القائمة للشاشات الأكبر حجمًا، استخدِم عرض القائمة التفصيلي لإظهار كلتا الميزتَين جنبًا إلى جنب في تخطيط مؤلف من جزأين. على عكس جزء الدعم، يعد جزء التفاصيل في عرض تفاصيل القائمة عنصرًا مستقلاً يمكن عرضه بشكل مستقل على الشاشات الأصغر.

استخدِم التطبيق المصغّر SlidingPaneLayout المخصّص لتنفيذ عرض تفاصيل القائمة. تحسب هذه الأداة تلقائيًا ما إذا كانت هناك مساحة كافية لعرض كلتا اللوحتين معًا بناءً على قيمة layout_width المحددة للجزأين، ويمكن توزيع أي مساحة متبقية باستخدام layout_weight. عندما لا تكون هناك مساحة كافية، يستخدم كل جزء العرض الكامل للتخطيط، وينزلق جزء التفاصيل خارج الشاشة أو أعلى جزء القائمة.

SlidingPaneLayout يعرض كلا جانبي تصميم قائمة بتفاصيل على جهاز بشاشة عريضة.
الشكل 5. SlidingPaneLayout يعرض جزأين بعرض موسّع وجزء واحد بعرض مضغوط.

يحتوي إنشاء تنسيق من لوحتين على مزيد من التفاصيل حول استخدام SlidingPaneLayout. لاحظ أيضًا أن هذا النمط قد يؤثر في كيفية هيكل الرسم البياني للتنقل (راجع التنقل لواجهات المستخدم سريعة الاستجابة).

مصادر إضافية