بدءًا من الإصدار 8.0 من نظام التشغيل Android (مستوى واجهة برمجة التطبيقات 26)، يتيح نظام Android تشغيل الأنشطة في وضع "نافذة ضمن النافذة" (PiP). "نافذة ضمن النافذة" هي نوع خاص من وضع النوافذ المتعددة يُستخدم لتشغيل الفيديوهات وإجراء مكالمات الفيديو والتنقّل. تتيح هذه الميزة للمستخدم تثبيت نافذة النشاط الحالية في إحدى زوايا الشاشة أثناء التنقّل بين التطبيقات أو تصفُّح المحتوى على الشاشة الرئيسية.
تستفيد ميزة "نافذة ضمن النافذة" من واجهات برمجة التطبيقات المتعددة النوافذ المتاحة في Android 7.0 لتوفير نافذة تراكب الفيديو المثبّتة. لإضافة ميزة "نافذة ضمن النافذة" إلى تطبيقك، عليك تسجيل الأنشطة التي تتوافق مع هذه الميزة، وتبديل نشاطك إلى وضع "نافذة ضمن النافذة" حسب الحاجة، والتأكّد من إخفاء عناصر واجهة المستخدم ومواصلة تشغيل الفيديو عندما يكون النشاط في وضع "نافذة ضمن النافذة".
تظهر نافذة "نافذة ضمن النافذة" في الطبقة العلوية من الشاشة، في زاوية يختارها النظام.
يتوافق وضع "نافذة ضمن النافذة" أيضًا مع أجهزة Android TV OS المتوافقة التي تعمل بالإصدار 14 من نظام التشغيل Android (مستوى واجهة برمجة التطبيقات 34) أو الإصدارات الأحدث. على الرغم من وجود العديد من أوجه التشابه، هناك اعتبارات إضافية عند استخدام ميزة نافذة ضمن النافذة على التلفزيون.
طُرق تفاعُل المستخدمين مع نافذة "نافذة ضمن النافذة"
يمكن للمستخدمين سحب نافذة "نافذة ضمن النافذة" إلى موقع آخر. اعتبارًا من Android 12، يمكن للمستخدمين أيضًا إجراء ما يلي:
انقر مرة واحدة على النافذة لعرض زر تبديل إلى وضع ملء الشاشة، وزر إغلاق، وزر إعدادات، وإجراءات مخصّصة يوفّرها تطبيقك (مثل عناصر التحكّم في التشغيل).
انقر مرّتين على النافذة للتبديل بين حجم "نافذة ضمن النافذة" الحالي والحد الأقصى أو الأدنى لحجمها، مثلاً، يؤدي النقر مرّتين على نافذة مكبّرة إلى تصغيرها، والعكس صحيح أيضًا.
إخفاء النافذة عن طريق سحبها إلى الحافة اليمنى أو اليسرى لإلغاء إخفاء النافذة، انقر على الجزء المرئي من النافذة المخفية أو اسحبها إلى الخارج.
غيِّر حجم نافذة "نافذة ضمن النافذة" باستخدام ميزة "التكبير والتصغير بإصبعَين".
يتحكّم تطبيقك في الوقت الذي ينتقل فيه النشاط الحالي إلى وضع "نافذة ضمن النافذة". في ما يلي بعض الأمثلة:
يمكن أن ينتقل النشاط إلى وضع "نافذة ضمن النافذة" عندما ينقر المستخدم على زر الشاشة الرئيسية أو عندما يسحب للأعلى للانتقال إلى الشاشة الرئيسية. بهذه الطريقة، تواصل "خرائط Google" عرض الاتجاهات بينما ينفّذ المستخدم نشاطًا آخر في الوقت نفسه.
يمكن لتطبيقك نقل فيديو إلى وضع "نافذة ضمن النافذة" عندما يعود المستخدم من الفيديو إلى تصفّح محتوى آخر.
يمكن لتطبيقك تبديل الفيديو إلى وضع "نافذة ضمن النافذة" أثناء مشاهدة المستخدم لنهاية حلقة من المحتوى. تعرض الشاشة الرئيسية معلومات ترويجية أو موجزة حول الحلقة التالية في السلسلة.
يمكن أن يوفّر تطبيقك طريقة للمستخدمين لإضافة محتوى إضافي إلى قائمة الانتظار أثناء مشاهدة فيديو. يستمر تشغيل الفيديو في وضع "نافذة ضمن النافذة" بينما تعرض الشاشة الرئيسية نشاط اختيار المحتوى.
الإفصاح عن إمكانية استخدام ميزة "نافذة ضمن النافذة"
لا يتيح النظام تلقائيًا استخدام وضع "نافذة ضمن النافذة" للتطبيقات. إذا أردت إتاحة ميزة "نافذة ضمن النافذة" في تطبيقك، عليك تسجيل نشاط الفيديو في ملف البيان من خلال ضبط android:supportsPictureInPicture على true. عليك أيضًا تحديد أنّ نشاطك يتعامل مع تغييرات إعدادات التصميم حتى لا تتم إعادة تشغيل النشاط عند حدوث تغييرات في التصميم أثناء عمليات الانتقال إلى وضع "نافذة ضمن النافذة".
<activity android:name="VideoActivity"
android:supportsPictureInPicture="true"
android:configChanges=
"screenSize|smallestScreenSize|screenLayout|orientation"
...
تنفيذ ميزة "نافذة ضمن النافذة" باستخدام Jetpack
استخدِم مكتبة "نافذة ضمن النافذة" في Jetpack لتنفيذ تجربة "نافذة ضمن النافذة"، لأنّها تسهّل عملية الدمج وتقلّل المشاكل الشائعة داخل التطبيق. راجِع نموذج تطبيق المنصة للاطّلاع على مثال على كيفية استخدامه. ومع ذلك، إذا كنت تفضّل تنفيذ ميزة "نافذة ضمن النافذة" باستخدام واجهات برمجة التطبيقات الخاصة بالنظام الأساسي، يمكنك الرجوع إلى المستندات التالية.
التبديل إلى وضع "نافذة ضمن النافذة"
بدءًا من الإصدار 12 من نظام Android، يمكنك التبديل إلى وضع "نافذة ضمن النافذة" من خلال ضبط العلامة setAutoEnterEnabled على true. باستخدام هذا الإعداد، يتم التبديل تلقائيًا إلى وضع "نافذة ضمن النافذة" عند الحاجة بدون الحاجة إلى استدعاء enterPictureInPictureMode() بشكلٍ صريح في onUserLeaveHint. ويوفّر ذلك ميزة إضافية تتمثّل في توفير انتقالات أكثر سلاسة. لمزيد من التفاصيل، يُرجى الاطّلاع على تسهيل الانتقال إلى وضع "نافذة ضمن النافذة" من خلال التنقّل بالإيماءات.
إذا كنت تستهدف الإصدار 11 من نظام التشغيل Android أو الإصدارات الأقدم، يجب أن يستدعي النشاط enterPictureInPictureMode() للتبديل إلى وضع "نافذة ضمن النافذة". على سبيل المثال، يعمل الرمز التالي على تبديل النشاط إلى وضع "نافذة ضمن النافذة" عندما ينقر المستخدم على زر مخصّص في واجهة مستخدم التطبيق:
override fun onActionClicked(action: Action) {
if (action.id.toInt() == R.id.lb_control_picture_in_picture) {
activity?.enterPictureInPictureMode()
return
}
}
قد تحتاج إلى تضمين منطق يغيّر النشاط إلى وضع "نافذة ضمن النافذة" بدلاً من الانتقال إلى الخلفية. على سبيل المثال، تنتقل "خرائط Google" إلى وضع "نافذة ضمن النافذة" إذا ضغط المستخدم على زر الصفحة الرئيسية أو زر التطبيقات الحديثة أثناء تنقّل التطبيق. يمكنك التعامل مع هذه الحالة من خلال إلغاء onUserLeaveHint():
override fun onUserLeaveHint() {
if (iWantToBeInPipModeNow()) {
enterPictureInPictureMode()
}
}
يُنصح بما يلي: توفير تجربة سلسة للمستخدمين عند الانتقال إلى وضع "نافذة ضمن النافذة"
أضاف الإصدار 12 من نظام التشغيل Android تحسينات كبيرة على المظهر العام لعمليات الانتقال المتحركة بين نوافذ وضع ملء الشاشة ووضع "نافذة ضمن النافذة". ننصحك بشدة بتنفيذ جميع التغييرات السارية، وبعد الانتهاء من ذلك، سيتم توسيع نطاق هذه التغييرات تلقائيًا ليشمل الشاشات الكبيرة، مثل الأجهزة القابلة للطي والأجهزة اللوحية، بدون الحاجة إلى أي عمل إضافي.
إذا كان تطبيقك لا يتضمّن التحديثات السارية، ستظل عمليات الانتقال إلى وضع "نافذة ضمن النافذة" تعمل، ولكن ستكون الرسوم المتحركة أقل سلاسة. على سبيل المثال، قد يؤدي الانتقال من وضع ملء الشاشة إلى وضع "نافذة ضمن النافذة" إلى اختفاء نافذة "نافذة ضمن النافذة" أثناء عملية الانتقال قبل أن تظهر مجددًا عند اكتمال عملية الانتقال.
تشمل هذه التغييرات ما يلي:
- تسهيل الانتقال إلى وضع "نافذة ضمن النافذة" من خلال التنقّل بالإيماءات
- ضبط
sourceRectHintمناسب للدخول إلى وضع "نافذة ضمن النافذة" والخروج منه - إيقاف ميزة تغيير الحجم بسلاسة للمحتوى غير المرئي
يمكنك الرجوع إلى نموذج "نافذة ضمن النافذة" في Android Kotlin كمرجع لتفعيل تجربة انتقال سلسة.
تسهيل الانتقال إلى وضع "نافذة داخل النافذة" من خلال التنقّل بالإيماءات
بدءًا من الإصدار 12 من نظام التشغيل Android، يوفّر العلامة setAutoEnterEnabled مؤثرًا حركيًا أكثر سلاسة عند الانتقال إلى محتوى الفيديو في وضع "نافذة ضمن النافذة" باستخدام ميزة التنقّل بالإيماءات، مثلاً عند التمرير سريعًا للأعلى إلى الشاشة الرئيسية من وضع ملء الشاشة.
أكمِل الخطوات التالية لإجراء هذا التغيير:
- استخدِم
setAutoEnterEnabledلإنشاءPictureInPictureParams.Builder:
setPictureInPictureParams(PictureInPictureParams.Builder()
.setAspectRatio(aspectRatio)
.setSourceRectHint(sourceRectHint)
.setAutoEnterEnabled(true)
.build())
Note: When `setAutoEnterEnabled` is enabled, you don't need to explicitly
call [`enterPictureInPictureMode`][5] in [`onUserLeaveHint`][6].
اتّصِل بالرقم
setPictureInPictureParamsباستخدامPictureInPictureParamsالحديث في وقت مبكر. لا ينتظر التطبيق دالة رد الاتصالonUserLeaveHint(كما كان يحدث في Android 11).على سبيل المثال، قد تحتاج إلى استدعاء
setPictureInPictureParamsعند التشغيل الأول وأي تشغيل لاحق في حال تغيير نسبة العرض إلى الارتفاع.اتّصِل بالرقم
setAutoEnterEnabled(false)عند الضرورة فقط. على سبيل المثال، من المحتمل أنّك لا تريد الانتقال إلى وضع "نافذة داخل النافذة" إذا كان التشغيل الحالي متوقفًا مؤقتًا.
ضبط sourceRectHint مناسب للدخول إلى وضع "نافذة ضمن النافذة" والخروج منه
منذ طرح ميزة "نافذة ضمن النافذة" في نظام التشغيل Android 8.0، كان الرمز setSourceRectHint
يشير إلى مساحة النشاط المرئية بعد الانتقال إلى وضع
نافذة ضمن النافذة، مثل حدود عرض الفيديو في مشغّل الفيديو.
في نظام التشغيل Android 12، يستخدم النظام sourceRectHint لتنفيذ حركة أكثر سلاسة عند الدخول إلى وضع "نافذة ضمن النافذة" والخروج منه.
لضبط sourceRectHint بشكلٍ سليم للدخول إلى وضع "نافذة ضمن النافذة" والخروج منه، اتّبِع الخطوات التالية:
- أنشئ
PictureInPictureParamsباستخدام الحدود المناسبة على النحو التالي:sourceRectHint. ننصحك أيضًا بإرفاق أداة معالجة تغيير التنسيق بمشغّل الفيديو:
val mOnLayoutChangeListener =
OnLayoutChangeListener { v: View?, left: Int,
top: Int, right: Int, bottom: Int, oldLeft: Int, oldTop:
Int, oldRight: Int, oldBottom: Int ->
val sourceRectHint = Rect()
mYourVideoView.getGlobalVisibleRect(sourceRectHint)
val builder = PictureInPictureParams.Builder()
.setSourceRectHint(sourceRectHint)
setPictureInPictureParams(builder.build())
}
mYourVideoView.addOnLayoutChangeListener(mOnLayoutChangeListener)
- إذا لزم الأمر، عدِّل
sourceRectHintقبل أن يبدأ النظام عملية الانتقال إلى حالة الخروج. عندما يكون النظام على وشك الخروج من وضع "نافذة ضمن النافذة"، يتم ترتيب هيكلية طرق العرض للنشاط وفقًا لإعدادات الوجهة (على سبيل المثال، ملء الشاشة). يمكن للتطبيق ربط أداة معالجة تغيير التنسيق بالعرض الجذر أو العرض المستهدف (مثل عرض مشغّل الفيديو) لرصد الحدث وتعديلsourceRectHintقبل بدء الحركة.
// Listener is called immediately after the user exits PiP but before animating.
playerView.addOnLayoutChangeListener { _, left, top, right, bottom,
oldLeft, oldTop, oldRight, oldBottom ->
if (left != oldLeft
|| right != oldRight
|| top != oldTop
|| bottom != oldBottom) {
// The playerView's bounds changed, update the source hint rect to
// reflect its new bounds.
val sourceRectHint = Rect()
playerView.getGlobalVisibleRect(sourceRectHint)
setPictureInPictureParams(
PictureInPictureParams.Builder()
.setSourceRectHint(sourceRectHint)
.build()
)
}
}
إيقاف ميزة تغيير الحجم بسلاسة للمحتوى غير المرتبط بالفيديو
يضيف الإصدار 12 من نظام التشغيل Android العلامة setSeamlessResizeEnabled، ما يوفّر تأثيرًا انتقاليًا أكثر سلاسة عند تغيير حجم المحتوى غير المرتبط بالفيديو في نافذة وضع "نافذة ضمن النافذة". في السابق، كان تغيير حجم المحتوى غير المرئي في نافذة ضمن النافذة يؤدي إلى ظهور تشوّهات مرئية.
لتفعيل تغيير الحجم بسلاسة لمحتوى الفيديو، اتّبِع الخطوات التالية:
setPictureInPictureParams(PictureInPictureParams.Builder()
.setSeamlessResizeEnabled(true)
.build())
التعامل مع واجهة المستخدم أثناء استخدام وضع "نافذة ضمن النافذة"
عندما يدخل النشاط إلى وضع "نافذة ضمن النافذة" (PiP) أو يخرج منه، يستدعي النظام الطريقتَين Activity.onPictureInPictureModeChanged() أو Fragment.onPictureInPictureModeChanged().
يقدِّم Android 15 تغييرات تضمن انتقالًا أكثر سلاسة عند تفعيل وضع "نافذة ضمن النافذة". ويفيد ذلك التطبيقات التي تتضمّن عناصر واجهة مستخدم معروضة فوق واجهة المستخدم الرئيسية التي يتم عرضها في وضع "نافذة ضمن النافذة".
يستخدم المطوّرون وظيفة الاستدعاء onPictureInPictureModeChanged() لتحديد المنطق الذي يتيح تبديل إمكانية ظهور عناصر واجهة المستخدم المتراكبة. يتم تشغيل دالة ردّ النداء هذه عند اكتمال حركة الدخول إلى وضع "نافذة ضمن النافذة" أو الخروج منه. بدءًا من Android 15، يتضمّن الصف PictureInPictureUiState حالة جديدة.
باستخدام حالة واجهة المستخدم الجديدة هذه، ستلاحظ التطبيقات التي تستهدف الإصدار 15 من نظام التشغيل Android أنّه يتم استدعاء عملية الاسترجاع Activity#onPictureInPictureUiStateChanged() مع isTransitioningToPip() فور بدء الصورة المتحركة لوضع "نافذة ضمن النافذة". هناك العديد من عناصر واجهة المستخدم التي لا صلة لها بالتطبيق عندما يكون في وضع "نافذة ضمن النافذة"، مثل طرق العرض أو التنسيق الذي يتضمّن معلومات مثل الاقتراحات والفيديو القادم والتقييمات والعناوين. عندما ينتقل التطبيق إلى وضع "نافذة ضمن النافذة"، استخدِم
onPictureInPictureUiStateChanged() للتعامل مع رد الاتصال لإخفاء عناصر واجهة المستخدم هذه. عندما ينتقل التطبيق إلى وضع ملء الشاشة من نافذة PiP، استخدِم معاودة الاتصال onPictureInPictureModeChanged() لإظهار هذه العناصر، كما هو موضّح في الأمثلة التالية:
override fun onPictureInPictureUiStateChanged(pipState: PictureInPictureUiState) {
if (pipState.isTransitioningToPip()) {
// Hide UI elements.
}
}
override fun onPictureInPictureModeChanged(
isInPictureInPictureMode: Boolean,
newConfig: Configuration
) {
super.onPictureInPictureModeChanged(isInPictureInPictureMode, newConfig)
if (!isInPictureInPictureMode) {
// Unhide UI elements.
}
}
يساعد مفتاح التبديل السريع هذا لعرض عناصر واجهة المستخدم غير ذات الصلة (لنافذة "صورة داخل صورة") في ضمان سلاسة حركة الدخول إلى وضع "صورة داخل صورة" بدون حدوث وميض.
يمكنك تجاهل عمليات معاودة الاتصال هذه لإعادة رسم عناصر واجهة المستخدم الخاصة بالنشاط. يُرجى العِلم أنّه في وضع "نافذة ضمن النافذة"، يظهر نشاطك في نافذة صغيرة. لا يمكن للمستخدمين التفاعل مع عناصر واجهة المستخدم في تطبيقك عندما يكون التطبيق في وضع "نافذة ضمن النافذة"، وقد يصعب رؤية تفاصيل عناصر واجهة المستخدم الصغيرة. توفّر أنشطة تشغيل الفيديو التي تتضمّن الحد الأدنى من عناصر واجهة المستخدم أفضل تجربة للمستخدم.
إذا كان تطبيقك بحاجة إلى توفير إجراءات مخصّصة لوضع "نافذة ضمن النافذة"، راجِع إضافة عناصر تحكّم في هذه الصفحة. أزِل عناصر واجهة المستخدم الأخرى قبل أن يدخل نشاطك وضع "نافذة ضمن النافذة"، وأعِدها عندما يصبح نشاطك بملء الشاشة مرة أخرى.
إضافة عناصر تحكّم
يمكن لنافذة "نافذة ضمن النافذة" عرض عناصر التحكّم عندما يفتح المستخدم قائمة النافذة (من خلال النقر على النافذة على جهاز جوّال أو اختيار القائمة من جهاز التحكّم عن بُعد الخاص بالتلفزيون).
إذا كان التطبيق يتضمّن جلسة وسائط نشطة، ستظهر عناصر التحكّم في التشغيل والإيقاف مؤقتًا والتالي والسابق.
يمكنك أيضًا تحديد إجراءات مخصّصة بشكل صريح من خلال إنشاء
PictureInPictureParams باستخدام
PictureInPictureParams.Builder.setActions() قبل الدخول إلى وضع "نافذة داخل النافذة"،
وتمرير المَعلمات عند الدخول إلى وضع "نافذة داخل النافذة" باستخدام
enterPictureInPictureMode(android.app.PictureInPictureParams) أو
setPictureInPictureParams(android.app.PictureInPictureParams). يجب توخّي الحذر. إذا حاولت إضافة أكثر من getMaxNumPictureInPictureActions()،
ستحصل على الحد الأقصى فقط.
مواصلة تشغيل الفيديو أثناء استخدام ميزة "نافذة ضمن النافذة"
عندما ينتقل نشاطك إلى وضع "نافذة ضمن النافذة"، يضعه النظام في حالة الإيقاف المؤقت ويستدعي طريقة onPause() الخاصة بالنشاط. يجب ألا يتم إيقاف تشغيل الفيديو مؤقتًا، بل يجب أن يستمر تشغيله إذا تم إيقاف النشاط مؤقتًا أثناء الانتقال إلى وضع "نافذة ضمن النافذة".
في نظام التشغيل Android 7.0 (المستوى 24 لواجهة برمجة التطبيقات) والإصدارات الأحدث، عليك إيقاف تشغيل الفيديو مؤقتًا واستئنافه عندما يستدعي النظام طريقتَي onStop() وonStart() في نشاطك. من خلال تنفيذ ذلك، يمكنك تجنُّب الحاجة إلى التحقّق مما إذا كان تطبيقك في وضع "نافذة ضمن النافذة" في onPause() ومواصلة التشغيل بشكل صريح.
إذا لم تضبط العلامة setAutoEnterEnabled على true وكنت بحاجة إلى إيقاف التشغيل مؤقتًا في تنفيذ onPause()، تحقّق من وضع "نافذة ضمن النافذة" من خلال استدعاء isInPictureInPictureMode() والتعامل مع التشغيل على النحو المناسب. على سبيل المثال:
override fun onPause() {
super.onPause()
// If called while in PiP mode, don't pause playback.
if (isInPictureInPictureMode) {
// Continue playback.
} else {
// Use existing playback logic for paused activity behavior.
}
}
عندما ينتقل نشاطك من وضع PiP إلى وضع ملء الشاشة، يستأنف النظام نشاطك ويستدعي طريقة onResume().
استخدام نشاط تشغيل واحد لوضع "نافذة ضمن النافذة"
في تطبيقك، قد يختار المستخدم فيديو جديدًا أثناء تصفّح المحتوى على الشاشة الرئيسية، بينما يكون نشاط تشغيل الفيديو في وضع "نافذة ضمن النافذة". تشغيل الفيديو الجديد في نشاط التشغيل الحالي بوضع ملء الشاشة، بدلاً من بدء نشاط جديد قد يربك المستخدم
لضمان استخدام نشاط واحد لطلبات تشغيل الفيديو والتبديل إلى وضع "نافذة ضمن النافذة" أو الخروج منه حسب الحاجة، اضبط قيمة android:launchMode للنشاط على singleTask في ملف البيان:
<activity android:name="VideoActivity"
...
android:supportsPictureInPicture="true"
android:launchMode="singleTask"
...
في نشاطك، يمكنك تجاهل onNewIntent() والتعامل مع الفيديو الجديد،
وإيقاف تشغيل أي فيديو حالي إذا لزم الأمر.
إتاحة وضع "نافذة ضمن النافذة" لتطبيقات الكاميرا
لتفعيل ميزة "نافذة ضمن النافذة" لتطبيقات الكاميرا، عليك التأكّد من أنّ الكاميرا تظل نشطة في وضع "نافذة ضمن النافذة" من خلال عدم إغلاق الكاميرا عند استدعاء onPause():
override fun onPause() {
super.onPause()
// Don't close the camera if the app is entering PiP mode
if (!isInPictureInPictureMode) {
closeCamera()
}
}
كما هو الحال مع حالات الاستخدام الأخرى، عليك إخفاء عناصر واجهة المستخدم غير الأساسية (مثل عناصر التحكّم والتراكبات)، وإضافة إجراءات مخصّصة للتحكّم في الكاميرا (على سبيل المثال، إيقاف التسجيل أو قلب الكاميرا).
احتساب sourceRectHint لإجراء انتقالات سلسة
من الضروري تقديم sourceRectHint دقيق مع إحداثيات الشاشة المحدّدة الخاصة بنافذة عرض الكاميرا لضمان سلاسة حركة الدخول. يمكنك الحصول على الحدود من عرض المعاينة باستخدام getGlobalVisibleRect() على النحو التالي:
val previewView = findViewById<View>(R.id.preview_view)
val globalRect = Rect()
// Ensure the view is laid out before calling getGlobalVisibleRect() to get valid screen coordinates.
previewView.getGlobalVisibleRect(globalRect)
val params = PictureInPictureParams.Builder()
.setSourceRectHint(globalRect)
.build()
setPictureInPictureParams(params)
اعتبارات أخرى
قد تكون ميزة "نافذة ضمن النافذة" غير مفعَّلة على الأجهزة التي تتضمّن ذاكرة وصول عشوائي (RAM) منخفضة. قبل أن يستخدم تطبيقك ميزة "نافذة ضمن النافذة"،
تحقَّق من توفّرها من خلال استدعاء
hasSystemFeature(PackageManager.FEATURE_PICTURE_IN_PICTURE).
تم تصميم ميزة "نافذة ضمن النافذة" للأنشطة التي تشغّل فيديوهات بملء الشاشة. عند التبديل إلى وضع "نافذة ضمن النافذة"، تجنَّب عرض أي شيء باستثناء محتوى الفيديو. تتبُّع الوقت الذي يدخل فيه نشاطك وضع "نافذة ضمن النافذة" وإخفاء عناصر واجهة المستخدم، كما هو موضّح في التعامل مع واجهة المستخدم أثناء وضع "نافذة ضمن النافذة"
عندما يكون النشاط في وضع "نافذة ضمن النافذة"، لا يحصل تلقائيًا على تركيز الإدخال. لتلقّي أحداث الإدخال أثناء استخدام وضع "نافذة ضمن النافذة"، استخدِم MediaSession.setCallback().
لمزيد من المعلومات حول استخدام setCallback()، يُرجى الاطّلاع على
عرض بطاقة "التعرّف التلقائي على الموسيقى".
عندما يكون تطبيقك في وضع "نافذة ضمن النافذة"، قد يؤدي تشغيل الفيديو في نافذة "نافذة ضمن النافذة" إلى حدوث تداخل صوتي مع تطبيق آخر، مثل تطبيق مشغّل موسيقى أو تطبيق بحث صوتي. ولتجنُّب ذلك، اطلب الحصول على أولويّة الصوت عند بدء تشغيل الفيديو، وتعامل مع الإشعارات المتعلقة بتغيير أولويّة الصوت، كما هو موضّح في إدارة أولويّة الصوت. إذا تلقّيت إشعارًا بفقدان أولويّة الصوت أثناء استخدام وضع "نافذة ضمن النافذة"، أوقِف تشغيل الفيديو مؤقتًا أو أوقِفه نهائيًا.
عندما يكون تطبيقك على وشك الدخول إلى وضع "نافذة ضمن النافذة"، ضَع في اعتبارك أنّ النشاط العلوي فقط هو الذي يدخل إلى وضع "نافذة ضمن النافذة". في بعض الحالات، مثل الأجهزة التي تتيح استخدام نوافذ متعدّدة، من المحتمل أن يظهر النشاط الأساسي ويصبح مرئيًا مرة أخرى إلى جانب نشاط وضع "نافذة ضمن النافذة". عليك التعامل مع هذه الحالة وفقًا لذلك، بما في ذلك تلقّي النشاط الأساسي لردّ اتصال onResume() أو onPause().
من المحتمل أيضًا أن يتفاعل المستخدم مع النشاط.
على سبيل المثال، إذا كان لديك نشاط قائمة فيديوهات معروضة ونشاط فيديو قيد التشغيل في وضع "نافذة ضمن النافذة"، قد يختار المستخدم فيديو جديدًا من القائمة ويجب تعديل نشاط "نافذة ضمن النافذة" وفقًا لذلك.
نموذج رموز برمجية إضافية
لتنزيل تطبيق نموذجي مكتوب بلغة Kotlin، اطّلِع على نموذج ميزة "نافذة ضمن النافذة" على Android (Kotlin).