يتيح التوافق مع أحجام الشاشات المختلفة الوصول إلى تطبيقك من خلال أكبر مجموعة متنوعة من الأجهزة وأكبر عدد من المستخدمين.
لإتاحة أكبر عدد ممكن من أحجام الشاشات، سواء كانت شاشات أجهزة مختلفة أو نوافذ تطبيقات مختلفة في وضع النوافذ المتعددة، صمِّم تنسيقات تطبيقاتك لتكون متجاوبة وتكيفية. توفر التصميمات السريعة الاستجابة/المتكيّفة تجربة مستخدم محسّنة بغض النظر عن حجم الشاشة، ما يتيح لتطبيقك أن يتوافق مع الهواتف والأجهزة اللوحية والأجهزة القابلة للطي وأجهزة ChromeOS ووضعيَي العرض العمودي والأفقي وإعدادات العرض القابلة لتغيير الحجم، مثل وضع تقسيم الشاشة والعرض في نافذة على الكمبيوتر.
تتغيّر التنسيقات المتجاوبة/القابلة للتكيّف استنادًا إلى مساحة العرض المتاحة. وتتراوح التغييرات بين تعديلات صغيرة على التنسيق تملأ المساحة (التصميم المتجاوب) واستبدال تنسيق بآخر بالكامل لكي يتوافق تطبيقك على أفضل نحو مع أحجام الشاشات المختلفة (التصميم المتكيّف).
باعتبارها مجموعة أدوات تعريفية لواجهة المستخدم، تُعدّ Jetpack Compose مثالية لتصميم وتنفيذ التنسيقات التي تتغيّر ديناميكيًا لعرض المحتوى بشكل مختلف على أحجام الشاشات المختلفة.
توضيح التغييرات الكبيرة في التصميم للعناصر القابلة للإنشاء على مستوى المحتوى
تشغل العناصر القابلة للإنشاء على مستوى التطبيق وعلى مستوى المحتوى كل مساحة العرض المتاحة لتطبيقك، لذا قد يكون من المنطقي تغيير التصميم العام لتطبيقك على الشاشات الكبيرة.
تجنَّب استخدام قيم الأجهزة المادية لاتّخاذ قرارات بشأن التصميم. قد يكون من المغري اتخاذ قرارات استنادًا إلى قيمة ملموسة ثابتة (هل الجهاز عبارة عن جهاز لوحي؟ (هل للشاشة الفعلية نسبة عرض إلى ارتفاع معيّنة؟)، ولكن قد لا تكون الإجابات عن هذه الأسئلة مفيدة لتحديد المساحة المتاحة لواجهة المستخدم.
على الأجهزة اللوحية، قد يتم تشغيل تطبيق في وضع النوافذ المتعددة، ما يعني أنّ التطبيق قد يقسّم الشاشة مع تطبيق آخر. في وضع النوافذ على أجهزة الكمبيوتر أو على ChromeOS، قد يكون التطبيق في نافذة قابلة لتغيير الحجم. قد يكون هناك أكثر من شاشة واحدة، كما هو الحال مع الأجهزة القابلة للطي. في كل هذه الحالات، لا يكون حجم الشاشة الفعلي مهمًا لتحديد طريقة عرض المحتوى.
بدلاً من ذلك، اتّخِذ قرارات استنادًا إلى الجزء الفعلي من الشاشة المخصّص لتطبيقك والموضّح من خلال مقاييس النافذة الحالية التي توفّرها مكتبة WindowManager من Jetpack. للاطّلاع على مثال حول كيفية استخدام WindowManager في تطبيق يستخدِم Compose، راجِع نموذج JetNews.
يؤدي جعل التصميمات تتكيّف مع مساحة العرض المتاحة إلى تقليل مقدار المعالجة الخاصة اللازمة لتوافقها مع منصات مثل ChromeOS وعوامل الشكل، مثل الأجهزة اللوحية والهواتف القابلة للطي.
بعد تحديد مقاييس المساحة المتاحة لتطبيقك، عليك تحويل الحجم الأولي إلى فئة حجم النافذة كما هو موضّح في استخدام فئات حجم النافذة. فئات أحجام النوافذ هي نقاط توقّف مصمَّمة لتحقيق التوازن بين بساطة منطق التطبيق والمرونة اللازمة لتحسين تطبيقك ليتوافق مع معظم أحجام الشاشات.
تشير فئات حجم النافذة إلى النافذة الإجمالية لتطبيقك، لذا استخدِم الفئات لاتّخاذ قرارات بشأن التصميم تؤثّر في التصميم العام لتطبيقك. يمكنك تمرير فئات حجم النافذة كحالة، أو يمكنك تنفيذ منطق إضافي لإنشاء حالة مشتقة لتمريرها إلى العناصر القابلة للإنشاء المتداخلة.
@Composable fun MyApp( windowSizeClass: WindowSizeClass = currentWindowAdaptiveInfo().windowSizeClass ) { // Decide whether to show the top app bar based on window size class. val showTopAppBar = windowSizeClass.isHeightAtLeastBreakpoint(WindowSizeClass.HEIGHT_DP_MEDIUM_LOWER_BOUND) // MyScreen logic is based on the showTopAppBar boolean flag. MyScreen( showTopAppBar = showTopAppBar, /* ... */ ) }
يقتصر النهج المتدرّج على منطق حجم العرض في مكان واحد بدلاً من توزيعه على عدة أماكن في تطبيقك يجب أن تظل متزامنة. ينتج عن الموقع الجغرافي الفردي حالة يمكن تمريرها بشكل صريح إلى عناصر أخرى قابلة للإنشاء، تمامًا مثل أي حالة أخرى للتطبيق. يؤدي تمرير الحالة بشكل صريح إلى تبسيط العناصر القابلة للإنشاء الفردية لأنّها تتلقّى فئة حجم النافذة أو الإعدادات المحدّدة مع البيانات الأخرى.
العناصر المركّبة المتداخلة المرنة قابلة لإعادة الاستخدام
تكون العناصر القابلة للإنشاء أكثر قابلية لإعادة الاستخدام عندما يمكن وضعها في مجموعة متنوعة من الأماكن. إذا كان يجب وضع عنصر قابل للإنشاء في موقع جغرافي محدّد وبحجم محدّد، من غير المرجّح أن يكون العنصر قابلاً لإعادة الاستخدام في سياقات أخرى. يعني هذا أيضًا أنّه يجب أن تتجنّب العناصر القابلة للإنشاء الفردية والقابلة لإعادة الاستخدام الاعتماد بشكل ضمني على معلومات حجم الشاشة العالمية.
لنفترض أنّ هناك عنصرًا قابلاً للإنشاء ومتداخلاً ينفّذ تنسيق قائمة وتفاصيل، والذي قد يعرض إما لوحة واحدة أو لوحتَين جنبًا إلى جنب:
يجب أن يكون قرار عرض القائمة والتفاصيل جزءًا من التصميم العام للتطبيق، لذا يتم تمرير القرار من عنصر قابل للإنشاء على مستوى المحتوى:
@Composable fun AdaptivePane( showOnePane: Boolean, /* ... */ ) { if (showOnePane) { OnePane(/* ... */) } else { TwoPane(/* ... */) } }
ماذا لو أردت بدلاً من ذلك أن يغيّر عنصر قابل للإنشاء تخطيطه بشكل مستقل استنادًا إلى مساحة العرض المتاحة، على سبيل المثال، بطاقة تعرض تفاصيل إضافية إذا كانت المساحة تسمح بذلك؟ تريد تنفيذ بعض العمليات المنطقية استنادًا إلى حجم عرض متوفّر، ولكن أي حجم تحديدًا؟
تجنَّب محاولة استخدام حجم شاشة الجهاز الفعلي. لن تكون هذه القيمة دقيقة لأنواع الشاشات المختلفة، ولن تكون دقيقة أيضًا إذا لم يكن التطبيق في وضع ملء الشاشة.
بما أنّ العنصر القابل للإنشاء ليس عنصرًا قابلاً للإنشاء على مستوى المحتوى، لا تستخدِم مقاييس النافذة الحالية مباشرةً.
إذا تم وضع المكوّن مع مساحة متروكة (مثل الحواف الداخلية)، أو إذا كان التطبيق يتضمّن مكوّنات مثل أشرطة التنقّل الجانبية أو أشرطة التطبيقات، قد يختلف مقدار مساحة العرض المتاحة للعنصر القابل للإنشاء اختلافًا كبيرًا عن المساحة الإجمالية المتاحة للتطبيق.
استخدِم العرض الذي يتم منحه للدالة البرمجية المركّبة لعرضها. يتوفّر لك خياران للحصول على هذا العرض:
إذا أردت تغيير مكان عرض المحتوى أو طريقة عرضه، استخدِم مجموعة من المعدِّلات أو تنسيقًا مخصّصًا لجعل التنسيق متجاوبًا. ويمكن أن يكون ذلك بسيطًا مثل ملء الطفل كل المساحة المتاحة، أو ترتيب الأطفال في أعمدة متعددة إذا كانت هناك مساحة كافية.
إذا أردت تغيير ما تعرضه، استخدِم
BoxWithConstraintsكبديل أكثر فعالية. توفّرBoxWithConstraintsقيود القياس التي يمكنك استخدامها لاستدعاء عناصر قابلة للإنشاء مختلفة استنادًا إلى مساحة العرض المتاحة. ومع ذلك، يتطلّب ذلك بعض التكاليف، لأنّBoxWithConstraintsيؤجّل عملية الإنشاء إلى مرحلة التنسيق، عندما تكون هذه القيود معروفة، ما يؤدي إلى تنفيذ المزيد من العمل أثناء التنسيق.
@Composable fun Card(/* ... */) { BoxWithConstraints { if (maxWidth < 400.dp) { Column { Image(/* ... */) Title(/* ... */) } } else { Row { Column { Title(/* ... */) Description(/* ... */) } Image(/* ... */) } } } }
إتاحة جميع البيانات لأحجام العرض المختلفة
عند تنفيذ عنصر قابل للإنشاء يستفيد من مساحة العرض الإضافية، قد تميل إلى أن تكون فعّالاً وتحمّل البيانات كتأثير جانبي لحجم العرض الحالي.
ومع ذلك، يتعارض ذلك مع مبدأ تدفّق البيانات أحادي الاتجاه، حيث يمكن رفع البيانات وتوفيرها للعناصر القابلة للإنشاء لعرضها بشكل مناسب. يجب توفير بيانات كافية للعنصر القابل للإنشاء لكي يتضمّن دائمًا محتوى كافيًا لأي حجم عرض، حتى إذا كان من المحتمل عدم استخدام جزء من المحتوى دائمًا.
@Composable fun Card( imageUrl: String, title: String, description: String ) { BoxWithConstraints { if (maxWidth < 400.dp) { Column { Image(imageUrl) Title(title) } } else { Row { Column { Title(title) Description(description) } Image(imageUrl) } } } }
استنادًا إلى مثال Card، تجدر الإشارة إلى أنّه يتم دائمًا تمرير description إلى Card. على الرغم من أنّ السمة description لا تُستخدَم إلا عندما يسمح العرض بعرضها، تتطلّب السمة Card دائمًا السمة description، بغض النظر عن العرض المتاح.
يؤدي تمرير محتوى كافٍ دائمًا إلى تبسيط التصاميم التكيّفية من خلال جعلها أقل اعتمادًا على الحالة، كما أنّه يمنع حدوث آثار جانبية عند التبديل بين أحجام الشاشة (التي قد تحدث بسبب تغيير حجم النافذة أو تغيير اتجاه الشاشة أو طي الجهاز وفتحه).
يسمح هذا المبدأ أيضًا بالحفاظ على الحالة عند تغيير التنسيق. من خلال نقل المعلومات التي قد لا يتم استخدامها في جميع أحجام الشاشات، يمكنك الحفاظ على حالة التطبيق عند تغيير حجم التنسيق.
على سبيل المثال، يمكنك رفع علامة منطقية showMore حتى يتم الحفاظ على حالة التطبيق عندما يؤدي تغيير حجم الشاشة إلى تبديل التنسيق بين إخفاء المحتوى وعرضه:
@Composable fun Card( imageUrl: String, title: String, description: String ) { var showMore by remember { mutableStateOf(false) } BoxWithConstraints { if (maxWidth < 400.dp) { Column { Image(imageUrl) Title(title) } } else { Row { Column { Title(title) Description( description = description, showMore = showMore, onShowMoreToggled = { newValue -> showMore = newValue } ) } Image(imageUrl) } } } }
مزيد من المعلومات
لمزيد من المعلومات حول التصميمات التكيّفية في Compose، يُرجى الاطّلاع على المراجع التالية:
تطبيقات نموذجية
- CanonicalLayouts هو مستودع لأنماط تصميم مثبتة توفر تجربة مستخدم مثالية على الشاشات الكبيرة
- يوضّح تطبيق JetNews كيفية تصميم تطبيق يكيّف واجهة المستخدم الخاصة به للاستفادة من مساحة العرض المتاحة.
- Reply هو نموذج متكيّف لدعم الأجهزة الجوّالة والأجهزة اللوحية والأجهزة القابلة للطي.
- Now in Android هو تطبيق يستخدم التصاميم التكيُّفية لإتاحة أحجام عرض مختلفة
الفيديوهات