النوافذ المتعددة في Android N: ما يحتاج المطورون إلى معرفته لتحقيق أقصى استفادة منه

نحن نقدم نظرة عامة على ما يعنيه دعم النوافذ المتعددة القادم في Android N للمطورين، وكيفية تحقيق أقصى استفادة منه!

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

كانت إحدى جلسات Google I/O مخصصة للمطورين للتعرف على واجهات برمجة التطبيقات الجديدة والتغييرات السلوكية للنظام التي يجلبها دعم النوافذ المتعددة.

تم تقديم الجلسة بواسطة Wale Ogunwale، المدير الفني لـ Android ActivityManager و مكونات إطار عمل WindowManager - هو وفريقه هم المسؤولون عن النوافذ المتعددة على نظام Android.

يمكنك مشاهدة جلسة وضع النوافذ المتعددة على YouTube، لكننا نقدم أيضًا نظرة عامة على الجلسة هنا.

يقدم N ثلاثة أوضاع مختلفة للنوافذ المتعددة:
  • وضع تقسيم الشاشة: هذا هو الوضع المتوفر افتراضيًا. كما يوحي الاسم، فهو يسمح لك بفتح تطبيقين جنبًا إلى جنب.
  • وضع الشكل الحر: يمكن للمصنعين تمكين هذا على الأجهزة الأكبر حجمًا، مما يسمح للمستخدمين بتغيير حجم الأنشطة بحرية بالإضافة إلى وضع تقسيم الشاشة.
  • وضع صورة داخل صورة: يستهدف هذا الوضع أجهزة Android TV، وهو مخصص لتشغيل مشغلات الفيديو في نافذة مثبتة أثناء تفاعل المستخدم مع التطبيقات الأخرى.
وضع تقسيم الشاشة لنظام Android Nوضع Android N PiP
ومن الجدير بالذكر أن. لقد قمنا بتغطية النوافذ المتعددة على N من قبل وقدمنا ​​بعض الانتقادات للنظام الحالي. مع أخذ ذلك في الاعتبار، نأمل أن يقترب الوضع الحر قليلاً من وضع الصورة داخل الصورة، حيث سيكون لذلك تطبيقات مفيدة على جميع الأجهزة.
يعد تمكين دعم النوافذ المتعددة في تطبيقاتك أمرًا بسيطًا: لن تحتاج إلى القيام بأي شيء إذا كنت تستهدف N بالفعل. إذا اخترت تعطيل النوافذ المتعددة، فيمكنك القيام بذلك عن طريق تعيين. android: resizeableActivity سمة النشاط في البيان الخاص بك إلى. false. يجب أن يتم ذلك فقط إذا كان له ما يبرره حقًا، لأنه يجعل تطبيقك يبرز بطريقة سيئة دائمًا التشغيل في وضع ملء الشاشة حتى إذا حاول المستخدم (أو تطبيق آخر) تشغيله في نوافذ متعددة وضع. من المهم ملاحظة أن سمات النشاط الجذري تنطبق على جميع الأنشطة ضمن مجموعة المهام الخاصة به. بمعنى آخر، إذا كان لديك نشاط يمكن تشغيله بواسطة تطبيقات أخرى، فتأكد من أنه يدعم وضع النوافذ المتعددة حيث لا يمكنك ضمان قيام التطبيقات الأخرى بتشغيل نشاطك في مهمة جديدة باستخدام. Intent#FLAG_ACTIVITY_NEW_TASK .يجب الإعلان عن دعم وضع الصورة داخل الصورة بشكل صريح عبر. android: supportsPictureInPicture يصف. لاحظ أنه يتم تجاهل هذه السمة إذا. android: resizeableActivity يكون. false يمكن استخدام سمات التخطيط لتعيين الأبعاد والموضع الافتراضي للنوافذ ذات الشكل الحر، أو لتحديد الحد الأدنى للعرض أو الارتفاع لكل من الوضعين الحر وتقسيم الشاشة:
  • android: defaultWidth/android: defaultHeight: الأبعاد الافتراضية للنشاط (الوضع الحر).
  • android: gravity: الموضع الأولي للنشاط (الوضع الحر).
  • android: minimalWidth/android: minimalHeight: الأبعاد الدنيا للنشاط (أوضاع الشكل الحر وتقسيم الشاشة)
يمكنك العثور على مثال التعليمات البرمجية في. نموذج لتطبيق Multi-Window Playground من Google على جيثب: AndroidManifest.xml.
مع تقديم دعم النوافذ المتعددة، قد تحتاج إلى التحقق مرة أخرى من بعض الأشياء في تطبيقاتك للتأكد من أنها تعمل بشكل صحيح.

فهم دورة حياة النشاط

ال. دورة حياة النشاط لم يتغير في وضع النوافذ المتعددة: دورة الحياة الأساسية لنشاط Android ومع ذلك، قد تؤدي بعض الاختلافات الدقيقة بين حالات النشاط إلى سلوك غير مقصود لم تكن لتلاحظه عادةً قبل N. من المهم معرفة ذلك. Activity#onResume() و. Activity#onPause() يتم استدعاؤها عندما يكتسب تطبيقك التركيز أو يفقده، ولكن ليس بالضرورة عندما يبدأ ظهوره أو يتوقف عن الظهور. (تذكر أنه قد يتم التركيز على تطبيق واحد فقط في أي وقت محدد.) بالنسبة للتطبيقات التي تقوم بتحديث المحتوى باستمرار (مثل تشغيل الفيديو)، تأكد من التعامل مع بدء تحديثات المحتوى وإيقافها. Activity#onStart() و. Activity#onStop() بدلاً من. عدم القيام بذلك لتطبيقات الفيديو، على سبيل المثال، سيعني أن التشغيل لن يحدث إلا إذا تم التركيز على التطبيق، مما يتعارض مع الغرض من وضع النوافذ المتعددة. واجه تطبيق YouTube الرسمي مشكلة مماثلة عندما تم إطلاق Android N Developer Preview لأول مرة.

التعامل مع تغييرات وقت التشغيل

عندما يتم وضع أحد التطبيقات في وضع النوافذ المتعددة، ستتغير بعض تكوينات الجهاز. يمكنك إما السماح بإعادة تشغيل نشاطك (في هذه الحالة. الاحتفاظ بالشظايا قد تكون فكرة جيدة، إذا كان نشاطك يجب أن يؤدي إلى عملية مكثفة عند بدء التشغيل)، أو اختر ذلك. التعامل مع تغييرات التكوين بشكل صريح بدلاً من. قد تتغير تكوينات الأجهزة الأربعة عند الدخول إلى وضع النوافذ المتعددة أو داخله: screenSize, smallestScreenSize, screenLayout و. orientation. الرجوع إلى. وثائق مطوري أندرويد لمزيد من المعلومات حول كل سمة، ولكن لاحظ ذلك. orientation لم يعد يشير إلى اتجاه الجهاز في هذه الحالة. بدلاً من ذلك، فهو يشير فقط إلى ما إذا كان عرض نشاطك أكبر من ارتفاعه (أفقي) أو ليس (صورة). يمكن الإعلان عن أن نشاطك سيتعامل مع هذه التغييرات من البيان:
android: name=".MyActivity"android: configChanges="screenSize|smallestScreenSize|screenLayout|orientation"/>
ضع في اعتبارك أن هذا يعني أنك ستحتاج بالفعل إلى التعامل مع هذه التغييرات. Activity#onConfigurationChanged()عن طريق تحديث طرق العرض يدويًا أو إعادة تحميل بعض الموارد.

الميزات المعطلة في وضع النوافذ المتعددة

لن تتأثر بعض ميزات النظام بأنشطتك أثناء وجودك في وضع النوافذ المتعددة:
  • لن يكون لتغييرات شريط الحالة وشريط التنقل، مثل تعتيم/إخفاء أشرطة النظام أو استخدام الوضع الشامل، أي تأثير. وهذا أمر منطقي نظرًا لأن نشاطك لا يشغل سوى جزء من الشاشة.
  • ال android: screenOrientation ليس لسمة النشاط أيضًا أي تأثير في وضع النوافذ المتعددة: نظرًا لأن نشاطك سيكون قابلاً لتغيير الحجم، فلم يعد من المنطقي أن يكون له اتجاه ثابت.
تمت إضافة عمليات رد اتصال جديدة لأحداث النوافذ المتعددة، بالإضافة إلى طرق للاستعلام عن الحالة الحالية.
  • Activity#onMultiWindowModeChanged(boolean inMultiWindow): يتم استدعاؤه عندما تتغير حالة النشاط من ملء الشاشة إلى نوافذ متعددة والعكس صحيح.
  • Activity#onPictureInPictureModeChanged(boolean inPictureOnPicture): يتم استدعاؤه عندما تتغير حالة النشاط من/إلى وضع PIP.
  • Activity#isInMultiWindowMode()/Activity#isInPictureInPictureMode(): إرجاع ما إذا كان النشاط في وضع النوافذ المتعددة/صورة داخل صورة أم لا.
  • Activity#overlayWithDecorCaption(boolean overlay): بالنسبة للنوافذ ذات الشكل الحر، يمكن استخدام هذه الطريقة لجعل التسمية التوضيحية (الشريط المستخدم لسحب النافذة حولها) تتراكب مع المحتوى بدلاً من دفعه لأسفل.
ملاحظة. ماعدا. Activity#overlayWithDecorCaption()، يتم توفير هذه الأساليب أيضًا بواسطة. Fragment فصل.

بدء الأنشطة في وضع النوافذ المتعددة

  • Activity#enterPictureInPictureMode() يمكن استخدامها لوضع نشاط في وضع صورة داخل صورة. لاحظ أن الأنشطة في وضع PiP لا يتم إخطارها بشأن أحداث الإدخال - استخدم MediaSession#setMediaButtonReceiver() إذا كنت تريد التعامل مع مثل هذه الأحداث. تأكد أيضًا من مراجعة موقع Android Developers إذا كنت مهتمًا بذلك صورة داخل صورة على Android N.
  • إذا كان الجهاز في وضع تقسيم الشاشة، فيمكنك إخبار النظام بتشغيل نشاط آخر بجانبك باستخدام Intent#FLAG_ACTIVITY_LAUNCH_ADJACENT علَم. ليس للعلم أي تأثير إذا لم يكن في وضع تقسيم الشاشة.
  • إذا كان الجهاز في الوضع الحر، ActivityOptions#setLaunchBounds() يمكن استخدامها لتحديد أبعاد النشاط الجديد وموقعه على الشاشة.
للحصول على أمثلة التعليمات البرمجية، راجع نموذج تطبيق Multi-Window Playground: مثال للنشاط المجاور, مثال على حدود الإطلاق.

السحب والإسقاط

على الرغم من أن دعم السحب والإسقاط كان موجودًا منذ تطبيق Honeycomb، إلا أنه كان ممكنًا في السابق فقط ضمن نفس النشاط. إنها تثلج. مدعومة في نافذة متعددة أيضًا. ويبدو أن تنفيذ هذا. في الغالب نفس كما كان من قبل، مع بعض الإضافات للسحب والإسقاط للأنشطة المشتركة:
  • View#startDragAndDrop()
    • الاسم المستعار الجديد ل View#startDrag().
    • لتمكين السحب والإفلات عبر الأنشطة، قم بتمرير العلامة الجديدة View#DRAG_FLAG_GLOBAL.
    • إذا كنت بحاجة إلى منح أذونات URI لنشاط المستلم، فقم بتمرير العلامات الجديدة View#DRAG_FLAG_GLOBAL_URI_READ أو View#DRAG_FLAG_GLOBAL_URI_WRITE، حسب الاقتضاء.
  • View#updateDragShadow()
    • يستبدل ظل السحب لعملية السحب الجارية حاليًا. لا يمكن استدعاؤه إلا من خلال التطبيق الذي أنشأ عملية السحب.
  • View#cancelDragAndDrop()
    • يلغي عملية السحب الجارية حاليًا. لا يمكن استدعاؤه إلا من خلال التطبيق الذي أنشأ عملية السحب.
  • يمكن التحقق مما إذا كان الجهاز يدعم أوضاع الشكل الحر أو الصورة داخل الصورة عبر PackageManager#hasSystemFeature()، استخدام PackageManager#FEATURE_FREEFORM_WINDOW_MANAGEMENT و PackageManager#FEATURE_FREEFORM_PICTURE_IN_PICTURE على التوالى.
  • ال android: windowBackground يمكن استخدام السمة كخلفية قابلة للرسم، إذا تم تغيير حجم النشاط وكان عرضه متأخرًا. لو android: windowBackground غير مضبوط، android: windowBackgroundFallback يستخدم بدلا من ذلك. ارجع إلى نموذج تطبيق Multi-Window Playground للحصول على مثال.
قدم Wale بعض أفضل الممارسات للتأكد من حصول المستخدمين على أفضل تجربة ممكنة:
  • يتغير وضع المقبض بأناقة:
    • الحفاظ على اتساق واجهة المستخدم بغض النظر عن الاتجاه. ليس لديك عناصر تغير مواضعها للسماح بالانتقالات السلسة.
    • التوسع في ما سبق، لا تقم بالتبديل بين التخطيطات المختلفة جدًا لتخطيطات الهاتف/الجهاز اللوحي. بدلاً من ذلك، قم بتكييف تخطيط الجهاز اللوحي لأحجام أصغر لتحقيق الاتساق.
  • تأكد من أن أنشطتك تتكيف مع الأحجام الصغيرة بواسطة اتباع أنماط تصميم المواد.
  • يستخدم FLAG_ACTIVITY_LAUNCH_ADJACENT عندما يكون من المنطقي تقديم تجربة أكثر متعة في وضع تقسيم الشاشة.
  • أعلن فقط عن عدم توافق تغيير الحجم عندما يكون ذلك مبررًا. كما ناقشنا أعلاه، فإنه يجعل تطبيقك يبرز بطريقة سيئة.
أنهى ويل الجلسة بتقديم بعض الموارد المفيدة الإضافية:
  • توثيق النوافذ المتعددة.
  • إرشادات تصميم المواد لوضع تقسيم الشاشة.
  • نموذج لتطبيق متعدد النوافذ.