التوافق مع الأجهزة القابلة للطي ثلاثية الطيات والأجهزة القابلة للطي في الوضع الأفقي

هاتف قابل للطي في الوضع الأفقي في وضعيتَي الإغلاق والفتح الكامل بجانب هاتف ثلاثي الطي في وضعيتَي الإغلاق والفتح الكامل

يواجه المطوّرون غالبًا صعوبات فريدة عند إنشاء تطبيقات للأجهزة القابلة للطي، خاصةً الأجهزة مثل Samsung Trifold أو Pixel Fold الأصلي الذي يفتح في الوضع الأفقي (rotation_0 = أفقي). تشمل أخطاء المطوّرين ما يلي:

  • افتراضات خاطئة بشأن اتجاه الجهاز
  • حالات الاستخدام التي يتم تجاهلها
  • تعذُّر إعادة احتساب القيم أو تخزينها مؤقتًا عند إجراء تغييرات في الإعدادات

تشمل المشاكل المحدّدة المتعلّقة بالجهاز ما يلي:

  • عدم تطابق الاتجاه الطبيعي للجهاز بين الشاشة الخارجية والداخلية (افتراضات تستند إلى rotation_0 = الوضع العمودي)، ما يؤدي إلى تعذُّر تشغيل التطبيقات عند طي الجهاز وفتحه
  • كثافات الشاشة المختلفة والتعامل غير الصحيح مع تغيير إعدادات الكثافة
  • مشاكل في معاينة الكاميرا بسبب اعتماد أداة الاستشعار في الكاميرا على الاتجاه الطبيعي

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

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

إنشاء تطبيق متوافق

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

التنسيقات التكيّفية

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

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

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

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

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

يستخدم المثال التالي مكتبة Material 3 المتكيّفة لتحديد المساحة المتاحة للتطبيق من خلال استدعاء الدالة currentWindowAdaptiveInfo() أولاً، ثم استخدام التصاميم المناسبة لفئات أحجام النوافذ الثلاث:

val adaptiveInfo = currentWindowAdaptiveInfo(supportLargeAndXLargeWidth = true)
val windowSizeClass = adaptiveInfo.windowSizeClass

when {
  windowSizeClass.isWidthAtLeastBreakpoint(WIDTH_DP_EXPANDED_LOWER_BOUND) -> // Large
  windowSizeClass.isWidthAtLeastBreakpoint(WIDTH_DP_MEDIUM_LOWER_BOUND) -> // Medium
  else -> // Compact
}

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

جودة التطبيقات على الشاشات الكبيرة

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

الإصدار 16 من نظام التشغيل Android والإصدارات الأحدث

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

اعتبارات خاصة

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

معاينة الكاميرا

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

الافتراضات غير المتطابقة

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

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

الحلّ 1: Jetpack CameraX (الأفضل)

أبسط الحلول وأكثرها فعالية هو استخدام مكتبة Jetpack CameraX. تم تصميم عنصر واجهة المستخدم PreviewView للتعامل مع جميع تعقيدات المعاينة تلقائيًا:

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

لمزيد من المعلومات، راجِع تنفيذ معاينة في مستندات CameraX.

الحلّ 2: CameraViewfinder

إذا كنت تستخدم قاعدة رموز برمجية حالية في Camera2، فإنّ مكتبة CameraViewfinder (متوافقة مع الإصدارات القديمة حتى المستوى 21 لواجهة برمجة التطبيقات) هي حلّ حديث آخر. ويسهّل عرض خلاصة الكاميرا من خلال استخدام TextureView أو SurfaceView وتطبيق جميع عمليات التحويل اللازمة (نسبة العرض إلى الارتفاع، والمقياس، والتدوير) نيابةً عنك.

لمزيد من المعلومات، يُرجى الاطّلاع على مشاركة المدونة تقديم ميزة "نافذة عرض الكاميرا" ودليل المطوّر معاينة الكاميرا.

الحلّ 3: تنفيذ Camera2 يدويًا

إذا تعذّر عليك استخدام CameraX أو CameraViewfinder، عليك احتساب الاتجاه ونسبة العرض إلى الارتفاع يدويًا والتأكّد من تعديل العمليات الحسابية عند كل تغيير في الإعدادات:

  • احصل على اتجاه أداة الاستشعار في الكاميرا (على سبيل المثال، 0 أو 90 أو 180 أو 270 درجة) من CameraCharacteristics.
  • الحصول على اتجاه تدوير الشاشة الحالي للجهاز (على سبيل المثال، 0 أو 90 أو 180 أو 270 درجة)
  • استخدِم هاتين القيمتين لتحديد عمليات التحويل اللازمة لـ SurfaceView أو TextureView.
  • تأكَّد من أنّ نسبة العرض إلى الارتفاع في الناتج Surface تتطابق مع نسبة العرض إلى الارتفاع في معاينة الكاميرا لتجنُّب التشويش.
  • قد يتم تشغيل تطبيق الكاميرا في جزء من الشاشة، إما في وضع النوافذ المتعددة أو وضع "العرض في نافذة" أو على شاشة عرض متصلة. لهذا السبب، يجب عدم استخدام حجم الشاشة لتحديد أبعاد عدسة الكاميرا، بل يجب استخدام مقاييس النافذة بدلاً من ذلك.

لمزيد من المعلومات، يُرجى الاطّلاع على دليل المطوّرين معاينة الكاميرا والفيديو تطبيق "الكاميرا" على أشكال الأجهزة المختلفة.

الحلّ 4: تنفيذ إجراءات أساسية للكاميرا باستخدام هدف

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

لمزيد من المعلومات، يُرجى الاطّلاع على أهداف الكاميرا.

الإعداد والاستمرارية

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

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

تشمل تغييرات الإعدادات التي يتم تشغيلها بشكل متكرّر screenSize وsmallestScreenSize وscreenLayout وorientation وdensity وfontScale وtouchscreen وkeyboard.

راجِع android:configChanges والتعامل مع تغييرات الإعدادات. للحصول على معلومات إضافية حول إدارة حالة التطبيق، اطّلِع على حفظ حالات واجهة المستخدم.

تغييرات إعدادات الكثافة

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

إعداد ملف AndroidManifest.xml

  • density: يشير إلى أنّ التطبيق سيتعامل مع تغيير كثافة الشاشة
  • تغييرات أخرى في الإعدادات: من المفيد أيضًا الإشارة إلى التغييرات الأخرى التي تحدث بشكل متكرر في الإعدادات، مثل screenSize وorientation وkeyboardHidden وfontScale وما إلى ذلك.

يؤدي تحديد الكثافة (وغيرها من تغييرات الإعدادات) إلى منع النظام من إعادة تشغيل النشاط، ويتم بدلاً من ذلك استدعاء onConfigurationChanged().

تنفيذ onConfigurationChanged()

عند حدوث تغيير في الكثافة، عليك تعديل الموارد (مثل إعادة تحميل الصور النقطية أو إعادة حساب أحجام التصميم) في دالة معاودة الاتصال:

  • تأكَّد من تغيير عدد النقاط في البوصة إلى newConfig.densityDpi
  • إعادة ضبط طرق العرض المخصّصة والعناصر القابلة للرسم المخصّصة وما إلى ذلك على الكثافة الجديدة

عناصر الموارد المطلوب معالجتها

  • مورد الصورة: استبدِل الصور النقطية والصور القابلة للرسم بموارد خاصة بالكثافة، أو اضبط المقياس مباشرةً
  • وحدة التنسيق (تحويل dp إلى px): إعادة احتساب حجم العرض والهامش والحشو
  • حجم الخط والنص: إعادة تطبيق حجم النص بوحدة sp
  • رسم View/Canvas مخصّص: تعديل القيم المستندة إلى وحدات البكسل المستخدَمة في الرسم Canvas

تحديد اتجاه التطبيق

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

الحلّ 1: استخدام Configuration.orientation

تحدّد هذه السمة اتجاه عرض تطبيقك حاليًا.

الحلّ 2: استخدام WindowMetrics#getBounds()

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

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

أوضاع الجهاز وأساليب العرض

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

لتمييز تطبيقك على الأجهزة القابلة للطي التي تتوافق مع HALF_OPENED، استخدِم واجهات برمجة التطبيقات Jetpack WindowManager، مثل FoldingFeature.

يمكنك الاطّلاع على مزيد من المعلومات حول أوضاع الأجهزة القابلة للطي وحالاتها وإمكانية معاينة الكاميرا في أدلة المطوّرين التالية:

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

قفل اتجاه الشاشة على اتجاه جهاز الاستشعار الطبيعي

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

<activity
  android:name=".MainActivity"
  android:screenOrientation="nosensor">

الألعاب وإعادة ربط أجهزة استشعار الواقع الممتد

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

لحلّ هذه المشكلة، تحقَّق من قيمة Display.getRotation() الحالية وأعِد ربط المحاور وفقًا لذلك:

  • الدوران 0: x=x, y=y
  • الدوران بزاوية 90 درجة: x=-y, y=x
  • تدوير بمقدار 180 درجة: x=-x, y=-y
  • التدوير بمقدار 270 درجة: x=y, y=-x

بالنسبة إلى متجهات الدوران (المستخدَمة في البوصلة أو تطبيقات الواقع الممتد)، استخدِم الدالة SensorManager.remapCoordinateSystem() لربط اتجاه عدسة الكاميرا أو أعلى الشاشة بالمحاور الجديدة استنادًا إلى الدوران الحالي.

توافق التطبيقات

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

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

لمزيد من المعلومات حول إنشاء تطبيقات متجاوبة، يُرجى الاطّلاع على جودة التطبيقات على الشاشات الكبيرة.