ضبط إعدادات تطبيقك في وضع "نافذة ضمن النافذة" (PIP)
تنظيم صفحاتك في مجموعات
يمكنك حفظ المحتوى وتصنيفه حسب إعداداتك المفضّلة.
في علامة النشاط لملف AndroidManifest.xml، نفِّذ ما يلي:
أضِف supportsPictureInPicture واضبطه على true للإفصاح عن أنّك ستتحكّم في استخدام وضع "صورة في صورة" في تطبيقك.
أضِف configChanges واضبطه على
orientation|screenLayout|screenSize|smallestScreenSize لتحديد أنّه
يعالج نشاطك تغييرات إعدادات التنسيق. بهذه الطريقة، لن تتم إعادة تشغيل نشاطك عند حدوث تغييرات في التنسيق أثناء الانتقالات إلى وضع "نافذة داخل النافذة".
أضِف هذه الإضافة على Context. ستستخدم هذه الإضافة عدة مرات
في جميع أقسام الدليل للوصول إلى النشاط.
internalfunContext.findActivity():ComponentActivity{varcontext=thiswhile(contextisContextWrapper){if(contextisComponentActivity)returncontextcontext=context.baseContext}throwIllegalStateException("Picture in picture should be called in the context of an Activity")}
إضافة ميزة "وضع الصورة في الصورة" عند مغادرة التطبيق على الإصدارات الأقدم من Android 12
لإضافة ميزة "وضع الصورة في الصورة" على الإصدارات الأقدم من Android 12، استخدِم الرمز addOnUserLeaveHintProvider. اتّبِع
الخطوات التالية لإضافة وضع "صورة في صورة" على الإصدارات الأقدم من Android 12:
أضِف بوابة إصدارات لكي لا يمكن الوصول إلى هذا الرمز إلا في الإصدارات من O إلى R.
أضِف addOnUserLeaveHintListener باستخدام findActivity() وأدخِل دالة lambda.
في onDispose، أضِف removeOnUserLeaveHintListener باستخدام findActivity()
وأدخِل دالة lambda.
if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.O&&
Build.VERSION.SDK_INT < Build.VERSION_CODES.S){valcontext=LocalContext.currentDisposableEffect(context){valonUserLeaveBehavior:()->Unit={context.findActivity().enterPictureInPictureMode(PictureInPictureParams.Builder().build())}context.findActivity().addOnUserLeaveHintListener(onUserLeaveBehavior)onDispose{context.findActivity().removeOnUserLeaveHintListener(onUserLeaveBehavior)}}}else{Log.i("PiP info","API does not support PiP")}
أضِف بيان if للتحقّق مما إذا كانت حزمة SDK من النوع S أو إصدار أحدث. إذا كان الأمر كذلك، أضِف
setAutoEnterEnabled إلى أداة الإنشاء واضبطه على true للدخول إلى وضع PiP
عند التمرير سريعًا. يقدّم هذا الإجراء رسومًا متحركة أكثر سلاسة من الانتقال إلى
enterPictureInPictureMode.
استخدِم findActivity() للاتصال برقم setPictureInPictureParams(). اتصل بـ build() على
builder وأرسِله.
استخدام setAspectRatio لضبط نسبة عرض إلى ارتفاع نافذة "وضع الصورة في الصورة"
لضبط نسبة العرض إلى الارتفاع لشاشة "صورة في صورة"، يمكنك اختيار نسبتَي عرض إلى ارتفاع معيّنتَين أو استخدام عرض الفيديو وارتفاعه في المشغّل. إذا كنت
تستخدم مشغّل media3، تأكَّد من أنّ المشغّل ليس فارغًا ومن أنّ
حجم الفيديو في المشغّل ليس مساويًا لـ [VideoSize.UNKNOWN][6] قبل ضبط ونسة
العرض إلى الارتفاع.
إذا كنت تستخدم مشغّلاً مخصّصًا، اضبط نسبة العرض إلى الارتفاع على ارتفاع
وعرض المشغّل باستخدام البنية الخاصة بالمشغّل. يُرجى العِلم أنّه إذا تم تغيير حجم المشغّل
أثناء الإعداد، سيتعطّل تطبيقك إذا خرج عن الحدود الصالحة لنسبة قياس الارتفاع إلى العرض. قد تحتاج إلى إضافة عمليات تحقّق حول
حالات احتساب نسبة العرض إلى الارتفاع، على غرار ما يتمّ تنفيذه في مشغّل الوسائط3.
يخضع كل من المحتوى وعيّنات التعليمات البرمجية في هذه الصفحة للتراخيص الموضحّة في ترخيص استخدام المحتوى. إنّ Java وOpenJDK هما علامتان تجاريتان مسجَّلتان لشركة Oracle و/أو الشركات التابعة لها.
تاريخ التعديل الأخير: 2025-08-27 (حسب التوقيت العالمي المتفَّق عليه)
[[["يسهُل فهم المحتوى.","easyToUnderstand","thumb-up"],["ساعَدني المحتوى في حلّ مشكلتي.","solvedMyProblem","thumb-up"],["غير ذلك","otherUp","thumb-up"]],[["لا يحتوي على المعلومات التي أحتاج إليها.","missingTheInformationINeed","thumb-down"],["الخطوات معقدة للغاية / كثيرة جدًا.","tooComplicatedTooManySteps","thumb-down"],["المحتوى قديم.","outOfDate","thumb-down"],["ثمة مشكلة في الترجمة.","translationIssue","thumb-down"],["مشكلة في العيّنات / التعليمات البرمجية","samplesCodeIssue","thumb-down"],["غير ذلك","otherDown","thumb-down"]],["تاريخ التعديل الأخير: 2025-08-27 (حسب التوقيت العالمي المتفَّق عليه)"],[],[],null,["In the activity tag of your `AndroidManifest.xml` file, do the following:\n\n1. Add `supportsPictureInPicture` and set it to `true` to declare you'll be using PiP in your app.\n2. Add `configChanges` and set it to\n `orientation|screenLayout|screenSize|smallestScreenSize` to specify that\n your activity handles layout configuration changes. This way, your activity\n doesn't relaunch when layout changes occur during PiP mode transitions.\n\n ```kotlin\n \u003cactivity\n android:name=\".SnippetsActivity\"\n android:exported=\"true\"\n android:supportsPictureInPicture=\"true\"\n android:configChanges=\"orientation|screenLayout|screenSize|smallestScreenSize\"\n android:theme=\"@style/Theme.Snippets\"\u003e\n ```\n | **Note:** To learn more about configuration changes, how to restrict activity recreation, and how to react to those configuration changes, see the [Handle\n | configuration changes](/guide/topics/resources/runtime-changes) page.\n\nIn your Compose code, do the following:\n\n1. Add this extension on `Context`. You'll use this extension multiple times throughout the guide to access the activity. \n\n ```kotlin\n internal fun Context.findActivity(): ComponentActivity {\n var context = this\n while (context is ContextWrapper) {\n if (context is ComponentActivity) return context\n context = context.baseContext\n }\n throw IllegalStateException(\"Picture in picture should be called in the context of an Activity\")\n }https://github.com/android/snippets/blob/7a0ebbee11495f628cf9d574f6b6069c2867232a/compose/snippets/src/main/java/com/example/compose/snippets/pictureinpicture/PictureInPictureSnippets.kt#L90-L97\n ```\n\nAdd PiP on leave app for pre-Android 12\n\nTo add PiP for pre-Android 12, use [`addOnUserLeaveHintProvider`](/reference/androidx/core/app/OnUserLeaveHintProvider). Follow\nthese steps to add PiP for pre-Android 12:\n\n1. Add a version gate so that this code is only accessed in versions O until R.\n2. Use a `DisposableEffect` with `Context` as the key.\n3. Inside the `DisposableEffect`, define the behavior for when the `onUserLeaveHintProvider` is triggered using a lambda. In the lambda, call [`enterPictureInPictureMode()`](/reference/android/app/Activity#enterPictureInPictureMode(android.app.PictureInPictureParams)) on `findActivity()` and pass in [`PictureInPictureParams.Builder().build()`](/reference/android/app/PictureInPictureParams.Builder).\n4. Add `addOnUserLeaveHintListener` using `findActivity()` and pass in the lambda.\n5. In `onDispose`, add `removeOnUserLeaveHintListener` using `findActivity()` and pass in the lambda.\n\n\n```kotlin\nif (Build.VERSION.SDK_INT \u003e= Build.VERSION_CODES.O &&\n Build.VERSION.SDK_INT \u003c Build.VERSION_CODES.S\n) {\n val context = LocalContext.current\n DisposableEffect(context) {\n val onUserLeaveBehavior: () -\u003e Unit = {\n context.findActivity()\n .enterPictureInPictureMode(PictureInPictureParams.Builder().build())\n }\n context.findActivity().addOnUserLeaveHintListener(\n onUserLeaveBehavior\n )\n onDispose {\n context.findActivity().removeOnUserLeaveHintListener(\n onUserLeaveBehavior\n )\n }\n }\n} else {\n Log.i(\"PiP info\", \"API does not support PiP\")\n}https://github.com/android/snippets/blob/7a0ebbee11495f628cf9d574f6b6069c2867232a/compose/snippets/src/main/java/com/example/compose/snippets/pictureinpicture/PictureInPictureSnippets.kt#L354-L374\n```\n\n\u003cbr /\u003e\n\nAdd PiP on leave app for post-Android 12\n\nPost-Android 12, the [`PictureInPictureParams.Builder`](/reference/android/app/PictureInPictureParams.Builder) is added through a\nmodifier that is passed to the app's video player.\n\n1. Create a `modifier` and call [`onGloballyPositioned`](/reference/kotlin/androidx/compose/ui/layout/OnGloballyPositionedModifier) on it. The layout coordinates will be used in a later step.\n2. Create a variable for the `PictureInPictureParams.Builder()`.\n3. Add an `if` statement to check if the SDK is S or above. If so, add [`setAutoEnterEnabled`](/reference/android/app/PictureInPictureParams.Builder#setAutoEnterEnabled(boolean)) to the builder and set it to `true` to enter PiP mode upon swipe. This provides a smoother animation than going through [`enterPictureInPictureMode`](/reference/android/app/Activity#enterPictureInPictureMode(android.app.PictureInPictureParams))().\n4. Use `findActivity()` to call `setPictureInPictureParams()`. Call `build()` on the `builder` and pass it in.\n\n\n```kotlin\nval pipModifier = modifier.onGloballyPositioned { layoutCoordinates -\u003e\n val builder = PictureInPictureParams.Builder()\n\n if (Build.VERSION.SDK_INT \u003e= Build.VERSION_CODES.S) {\n builder.setAutoEnterEnabled(true)\n }\n context.findActivity().setPictureInPictureParams(builder.build())\n}\nVideoPlayer(pipModifier)https://github.com/android/snippets/blob/7a0ebbee11495f628cf9d574f6b6069c2867232a/compose/snippets/src/main/java/com/example/compose/snippets/pictureinpicture/PictureInPictureSnippets.kt#L74-L82\n```\n\n\u003cbr /\u003e\n\nUse `setAspectRatio` to set PiP window's aspect ratio\n\nTo set the aspect ratio of the PiP window, you can either choose a specific\naspect ratio or use the width and height of the player's video size. If you are\nusing a media3 player, check that the player is not null and that the player's\nvideo size is not equal to \\[`VideoSize.UNKNOWN`\\]\\[6\\] before setting the aspect\nratio.\n\n\n```kotlin\nval context = LocalContext.current\n\nval pipModifier = modifier.onGloballyPositioned { layoutCoordinates -\u003e\n val builder = PictureInPictureParams.Builder()\n if (shouldEnterPipMode && player != null && player.videoSize != VideoSize.UNKNOWN) {\n val sourceRect = layoutCoordinates.boundsInWindow().toAndroidRectF().toRect()\n builder.setSourceRectHint(sourceRect)\n builder.setAspectRatio(\n Rational(player.videoSize.width, player.videoSize.height)\n )\n }\n\n if (Build.VERSION.SDK_INT \u003e= Build.VERSION_CODES.S) {\n builder.setAutoEnterEnabled(shouldEnterPipMode)\n }\n context.findActivity().setPictureInPictureParams(builder.build())\n}\n\nVideoPlayer(pipModifier)https://github.com/android/snippets/blob/7a0ebbee11495f628cf9d574f6b6069c2867232a/compose/snippets/src/main/java/com/example/compose/snippets/pictureinpicture/PictureInPictureSnippets.kt#L248-L266\n```\n\n\u003cbr /\u003e\n\n| **Warning:** The bounds of what the aspect ratio can be are between 2.39:1 and 1:2.39 (inclusive). If your aspect ratio does not fall between these values, your app will crash.\n\nIf you are using a custom player, set the aspect ratio on the player's height\nand width using the syntax specific to your player. Be aware that if your player\nresizes during initialization, if it falls outside of the valid bounds of what\nthe aspect ratio can be, your app will crash. You may need to add checks around\nwhen the aspect ratio can be calculated, similar to how it is done for a media3\nplayer."]]