إدارة النوافذ

يتوافق نظام التشغيل ChromeOS مع تطبيقات Android في نوافذ متعددة. يعرض النظام التطبيقات في حاويات نوافذ يتم تحديد حجمها حسب شكل الجهاز، كما هو موضّح في الشكل 1.

نافذة تطبيق على أجهزة مختلفة
الشكل 1.: يظهر الوصف هنا.

الشكل 1: نافذة تطبيق على أجهزة مختلفة

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

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

حجم الإطلاق الأوّلي

يمكن للتطبيقات طلب حجم التشغيل الأوّلي بالطرق التالية:

  • استخدِم حجم الإطلاق في بيئات سطح المكتب فقط. يساعد ذلك مدير النوافذ في منحك الحدود والاتجاه المناسبَين. للإشارة إلى إعدادات مفضّلة عند استخدامها في وضع الكمبيوتر المكتبي، أضِف العلامات الوصفية التالية داخل <activity>:

    &lt;meta-data android:name=&#34;WindowManagerPreference:FreeformWindowSize&#34;
               android:value=&#34;[phone|tablet|maximize]&#34; /&gt;
    &lt;meta-data android:name=&#34;WindowManagerPreference:FreeformWindowOrientation&#34;
               android:value=&#34;[portrait|landscape]&#34; /&gt;
    
  • استخدِم حدود تشغيل ثابتة. استخدِم <layout> داخل إدخال البيان الخاص بنشاطك لتحديد حجم بدء "ثابت"، كما هو موضّح في المثال التالي:

    &lt;layout android:defaultHeight=&#34;500dp&#34;
                android:defaultWidth=&#34;600dp&#34;
                android:gravity=&#34;top|end&#34;
                android:minHeight=&#34;450dp&#34;
                android:minWidth=&#34;300dp&#34; /&gt;
    
  • استخدام حدود التشغيل الديناميكية يمكن لأحد الأنشطة إنشاء واستخدام ActivityOptions.setLaunchBounds(Rect) عند إنشاء نشاط جديد. من خلال تحديد مستطيل فارغ، يمكن تكبير تطبيقك.

تغيير حجم النوافذ

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

الشكل 2.: يظهر الوصف هنا.

الشكل 2: نافذة تطبيق يمكن تغيير حجمها

هناك خياران للتعامل مع تغيير حجم النافذة عند استخدام الفئة View:

  • الاستجابة لتغييرات الإعدادات بشكل ديناميكي من خلال استدعاء onConfigurationChanged(..) على سبيل المثال، يمكنك إضافة android:configChanges="screenSize|smallestScreenSize|orientation|screenLayout" إلى ملف البيان الخاص بالنشاط. لمزيد من المعلومات حول التعامل مع تغييرات الإعدادات، يُرجى قراءة مقالة التعامل مع تغييرات الإعدادات.
  • اسمح للنظام بإعادة تشغيل النشاط. في هذه الحالة، عليك تنفيذ onSaveInstanceState واستخدام مكوّن بنية ViewModel لاستعادة الحالة المحفوظة السابقة.

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

أبعاد النافذة

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

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

يُرجى العِلم أنّ حجم النافذة وحجم الشاشة ليسا متطابقَين. للحصول على حجم النافذة بوحدات بكسل مستقلة الكثافة، استخدِم Activity.getResources().getConfiguration().screenWidth وActivity.getResources().getConfiguration().screenHeight. من المحتمل ألا تحتاج إلى استخدام حجم الشاشة أبدًا.

حدود المحتوى

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

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

    • NativeActivity.mLastContent[X/Y/Width/Height]()
    • findViewById(android.R.id.content).get[Width/Height]()

    يمكن إجراء المراقبة المستمرة باستخدام مراقب:

    • NativeActivity.onContentRectChangedNative()
    • NativeActivity.onGlobalLayout()
    • إضافة مستمع إلى view.addOnLayoutChangeListener(findViewById(android.R.id.content))

    إذا كان التطبيق يغيّر حجم العمل الفني مسبقًا، يجب إجراء ذلك في كل مرة تتغير فيها الدقة.

تغيير الحجم بحرية

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

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

وضع ملء الشاشة

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

اتجاه الشاشة

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

تفترض بعض تطبيقات Android أنّه عندما يتم حمل الجهاز في الوضع العمودي، تكون قيمة التدوير هي Surface.ROTATION_0. قد ينطبق ذلك على معظم أجهزة Android. ومع ذلك، عندما يكون التطبيق في وضع ARC معيّن، قد لا تكون قيمة التدوير للوضع العمودي هي Surface.ROTATION_0.

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

النشاط الأساسي والاتجاه

تتألف نافذة Chromebook من مجموعة من نوافذ الأنشطة. ويكون لكل نافذة في الحزمة الحجم والاتجاه نفسهما.

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

يؤثر وضع الجهاز في هذه الحالة: في وضع الجهاز اللوحي، لا يتم قفل اتجاه الشاشة، ويحتفظ كل تطبيق باتجاهه الخاص، كما هو معتاد على Android.

إرشادات حول الاتجاه

اتّبِع الإرشادات التالية للتعامل مع اتجاه الشاشة:

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

اعتبارات أخرى

في ما يلي بعض الأمور الأخرى التي يجب مراعاتها عند استخدام تطبيقات Android في ChromeOS:

  • لا تستدعِ finish() في الإجراء onDestroy الخاص بالنشاط. يؤدي ذلك إلى إغلاق التطبيق عند تغيير حجمه وعدم إعادة تشغيله.
  • لا تستخدِم أنواع نوافذ غير متوافقة، مثل TYPE_KEYGUARD وTYPE_APPLICATION_MEDIA.
  • يمكنك تسريع عمليات إعادة تشغيل الأنشطة من خلال تخزين العناصر التي تم تخصيصها سابقًا مؤقتًا.
  • إذا كنت لا تريد أن يغيّر المستخدم حجم تطبيقك، حدِّد android:resizeableActivity=false في ملف البيان.
  • اختبِر تطبيقك للتأكّد من أنّه يتعامل مع التغييرات في حجم النافذة بشكلٍ مناسب.