تصميم سريع الاستجابة/تكيّفي مع عدد مشاهدات

تجربة طريقة "الكتابة"
‫Jetpack Compose هي مجموعة أدوات واجهة المستخدم المقترَحة لنظام التشغيل Android. تعرَّف على كيفية استخدام التنسيقات المتجاوبة في Compose.

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

التصميم السريع الاستجابة

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

ConstraintLayout

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

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

الشكل 3. تعرض "أداة تعديل التنسيق" في "استوديو Android" ConstraintLayout.

لمزيد من المعلومات، يُرجى الاطّلاع على إنشاء واجهة مستخدم متجاوبة باستخدام ConstraintLayout.

العرض والارتفاع المتجاوبان

لضمان أن يكون التنسيق متجاوبًا مع أحجام العرض المختلفة، استخدِم wrap_content أو match_parent أو 0dp (match constraint) لعرض وارتفاع مكوّنات العرض بدلاً من القيم المرمّزة ثابتة:

  • wrap_content: يضبط العرض حجمه ليتناسب مع المحتوى الذي يتضمّنه.
  • match_parent: يتم توسيع العرض قدر الإمكان ضمن العرض الرئيسي.
  • 0dp (match constraint): في ConstraintLayout، على غرار match_parent تستغل طريقة العرض كل المساحة المتاحة ضمن قيود طريقة العرض.

على سبيل المثال:

<TextView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="@string/lorem_ipsum" />

يوضّح الشكل 4 كيف يتغير عرض وارتفاع TextView عند تغيُّر عرض الشاشة مع اتجاه الجهاز.

الشكل 4. TextView سريع الاستجابة

يضبط TextView عرضه لملء كل المساحة المتاحة (match_parent)، ويضبط ارتفاعه ليكون مساويًا تمامًا للمساحة التي يتطلبها ارتفاع النص المضمّن (wrap_content)، ما يتيح للعرض التكيّف مع أبعاد العرض المختلفة وكميات النص المختلفة.

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

يمكن أن تنشئ ConstraintLayout جميع التنسيقات الممكنة تقريبًا باستخدام LinearLayout بدون التأثير في الأداء، لذا حوِّل LinearLayout المتداخلة إلى ConstraintLayout. بعد ذلك، يمكنك تحديد تنسيقات مرجّحة باستخدام سلاسل القيود.

التصميم التكيّفي

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

SlidingPaneLayout لواجهات المستخدم التي تعرض على شكل قائمة مع تفاصيل

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

تتولّى SlidingPaneLayout إدارة منطق تحديد تجربة المستخدم المناسبة لحجم النافذة الحالي من بين تجربتَي المستخدمَين:

<?xml version="1.0" encoding="utf-8"?>
<androidx.slidingpanelayout.widget.SlidingPaneLayout
    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:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recycler_view"
        android:layout_width="280dp"
        android:layout_height="match_parent"
        android:layout_gravity="start" />

    <androidx.fragment.app.FragmentContainerView
        android:id="@+id/nav_host_fragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="300dp"
        android:layout_height="match_parent"
        android:layout_weight="1"
        app:defaultNavHost="true"
        app:navGraph="@navigation/item_navigation" />

</androidx.slidingpanelayout.widget.SlidingPaneLayout>

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

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

موارد التصميم البديلة

لتكييف تصميم واجهة المستخدم مع أحجام العرض المختلفة بشكل كبير، استخدِم تنسيقات بديلة يتم تحديدها من خلال محدّدات جودة الموارد.

الشكل 5. التطبيق نفسه يستخدم تخطيطات مختلفة لأحجام عرض مختلفة.

يمكنك توفير تنسيقات متجاوبة ومناسبة للشاشة من خلال إنشاء أدلة res/layout/ إضافية في الرمز المصدر لتطبيقك. أنشئ دليلاً لكل إعداد شاشة يتطلّب تنسيقًا مختلفًا. بعد ذلك، أضِف أداة تحديد مواصفات إعدادات الشاشة إلى اسم الدليل layout (على سبيل المثال، layout-w600dp للشاشات التي يبلغ عرضها المتاح 600 وحدة بكسل مستقلة الكثافة).

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

لإنشاء تصاميم بديلة في &quot;استوديو Android&quot;، راجِع مقالة استخدام أشكال التصاميم المختلفة لتحسين التطبيق ليتوافق مع الشاشات المختلفة في تطوير واجهة مستخدم باستخدام طرق العرض.

معدِّل أصغر عرض

يتيح لك مؤهّل حجم الشاشة أصغر عرض توفير تنسيقات بديلة للشاشات التي يبلغ الحد الأدنى لعرضها وحدات بكسل مستقلة الكثافة (dp).

من خلال وصف حجم الشاشة كمقياس لوحدات dp، يتيح لك نظام التشغيل Android إنشاء تنسيقات مصمَّمة لأبعاد عرض معيّنة بدون الحاجة إلى مراعاة كثافات البكسل المختلفة.

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

res/layout/main_activity.xml           # For phones (smaller than 600dp smallest width)
res/layout-sw600dp/main_activity.xml   # For 7" tablets (600dp wide or wider)

يحدّد مؤهّل أصغر عرض أصغر جانبَين للشاشة، بغض النظر عن الاتجاه الحالي للجهاز، لذا فهو طريقة لتحديد حجم الشاشة الإجمالي المتاح للتصميم.

في ما يلي كيفية توافق قيم أصغر عرض الأخرى مع أحجام الشاشات النموذجية:

  • ‫320 بكسل مستقل الكثافة: شاشة هاتف صغيرة (240×320 بكسل مستقل الكثافة منخفضة الكثافة، و320×480 بكسل مستقل الكثافة متوسطة الكثافة، و480×800 بكسل مستقل الكثافة عالية الكثافة، وما إلى ذلك)
  • ‫480 بكسل مستقل الكثافة: شاشة هاتف كبيرة بحجم 5 بوصة تقريبًا (480x800 نقطة في البوصة mdpi)
  • ‫600 وحدة بكسل مستقلة عن الكثافة: جهاز لوحي مقاس 7 بوصة (600 × 1024 وحدة بكسل مستقلة عن الكثافة)
  • ‫720dp: جهاز لوحي بحجم 10 بوصة (‫720×1280 mdpi أو ‫800×1280 mdpi أو غير ذلك)

يقدّم الشكل التالي عرضًا أكثر تفصيلاً حول كيفية توافق عروض dp المختلفة للشاشة مع أحجام الشاشات واتجاهاتها المختلفة.

الشكل 6. نقاط التوقف الموصى بها للعرض من أجل توفير التوافق مع أحجام الشاشات المختلفة

تكون قيم معرّف أصغر عرض هي dp، لأنّ المهم هو مقدار مساحة العرض المتاحة بعد أن يأخذ النظام في الاعتبار كثافة البكسل (وليس دقة البكسل الأولية).

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

محدّد العرض المتاح

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

res/layout/main_activity.xml         # For phones (smaller than 600dp available width)
res/layout-w600dp/main_activity.xml  # For 7" tablets or any screen with 600dp available width
                                     # (possibly landscape phones)

إذا كان الارتفاع المتاح يمثّل مشكلة لتطبيقك، يمكنك استخدام أداة تحديد الارتفاع المتاح. على سبيل المثال، layout-h600dp للشاشات التي يبلغ ارتفاعها 600 وحدة بكسل مستقلة الكثافة على الأقل.

مؤهلات الاتجاه

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

لإجراء ذلك، يمكنك إضافة المحددات port أو land إلى أسماء دليل التصميم. ما عليك سوى التأكّد من أنّ مؤهّلات اتجاه الشاشة تأتي بعد مؤهّلات الحجم. على سبيل المثال:

res/layout/main_activity.xml                # For phones
res/layout-land/main_activity.xml           # For phones in landscape
res/layout-sw600dp/main_activity.xml        # For 7" tablets
res/layout-sw600dp-land/main_activity.xml   # For 7" tablets in landscape

لمزيد من المعلومات حول جميع مؤهلات إعدادات الشاشة، راجِع نظرة عامة على موارد التطبيق.

فئات حجم النافذة

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

لتطبيق التصاميم التكيّفية آليًا، اتّبِع الخطوات التالية:

  • إنشاء موارد التنسيق استنادًا إلى نقاط توقّف فئة حجم النافذة
  • احتساب فئات حجم النافذة من حيث العرض والارتفاع في تطبيقك باستخدام الدالة WindowSizeClass#compute() من مكتبة Jetpack WindowManager
  • توسيع مورد التنسيق لفئات حجم النافذة الحالية

لمزيد من المعلومات، يُرجى الاطّلاع على فئات حجم النافذة.

مكوّنات واجهة المستخدم المجزّأة باستخدام الأجزاء

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

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

لمزيد من المعلومات، يُرجى الاطّلاع على نظرة عامة حول المقاطع.

تضمين الأنشطة

إذا كان تطبيقك يتضمّن أنشطة متعددة، تتيح لك ميزة "تضمين الأنشطة" إنشاء واجهة مستخدم قابلة للتكيّف بسهولة.

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

يمكنك تحديد طريقة عرض تطبيقك لأنشطته من خلال إنشاء ملف إعداد بتنسيق XML يستخدمه النظام لتحديد طريقة العرض المناسبة استنادًا إلى حجم الشاشة. يمكنك بدلاً من ذلك إجراء طلبات إلى Jetpack WindowManager API.

تتيح ميزة "تضمين الأنشطة" تغيير اتجاه الجهاز والأجهزة القابلة للطي، وتكديس الأنشطة وإلغاء تكديسها عند تدوير الجهاز أو طيّه وفتحه.

لمزيد من المعلومات، يُرجى الاطّلاع على تضمين النشاط.

أحجام الشاشة ونِسب العرض إلى الارتفاع

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

يتوافق الإصدار 10 من نظام التشغيل Android (المستوى 29 لواجهة برمجة التطبيقات) والإصدارات الأحدث مع مجموعة كبيرة من نسب العرض إلى الارتفاع. يمكن أن تختلف أشكال الأجهزة القابلة للطي من شاشات طويلة وضيقة، مثل 21:9 عند طيها، إلى نسبة عرض إلى ارتفاع مربّعة تبلغ 1:1 عند فتحها.

لضمان التوافق مع أكبر عدد ممكن من الأجهزة، اختبِر تطبيقاتك على أكبر عدد ممكن من نسب العرض إلى الارتفاع التالية للشاشة:

الشكل 7. نِسب عرض إلى ارتفاع مختلفة للشاشة

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

إذا كنت تفضّل إجراء الاختبار على جهاز حقيقي ولكن لا يتوفّر لديك جهاز، يمكنك استخدام مركز الاختبار الافتراضي لمنصة Firebase للوصول إلى الأجهزة في مركز بيانات Google.

مراجع إضافية