Thiết lập ứng dụng để dùng tính năng PiP (Hình trong hình)
Sử dụng bộ sưu tập để sắp xếp ngăn nắp các trang
Lưu và phân loại nội dung dựa trên lựa chọn ưu tiên của bạn.
Trong thẻ hoạt động của tệp AndroidManifest.xml, hãy làm như sau:
Thêm supportsPictureInPicture và đặt thành true để khai báo rằng bạn sẽ sử dụng tính năng PiP trong ứng dụng.
Thêm configChanges và đặt thành orientation|screenLayout|screenSize|smallestScreenSize để chỉ định rằng hoạt động của bạn xử lý các thay đổi về cấu hình bố cục. Bằng cách này, hoạt động của bạn sẽ không chạy lại khi các thay đổi về bố cục xảy ra trong quá trình chuyển đổi chế độ PiP.
Thêm tiện ích này trên Context. Bạn sẽ sử dụng tiện ích này nhiều lần trong suốt hướng dẫn để truy cập vào hoạt động.
internalfunContext.findActivity():ComponentActivity{varcontext=thiswhile(contextisContextWrapper){if(contextisComponentActivity)returncontextcontext=context.baseContext}throwIllegalStateException("Picture in picture should be called in the context of an Activity")}
Thêm PiP khi rời khỏi ứng dụng cho phiên bản Android trước 12
Để thêm PiP cho các phiên bản Android trước 12, hãy sử dụng addOnUserLeaveHintProvider. Làm theo các bước sau để thêm PiP cho các phiên bản Android trước Android 12:
Thêm một cổng phiên bản để mã này chỉ được truy cập trong các phiên bản O cho đến R.
Thêm addOnUserLeaveHintListener bằng findActivity() và truyền vào lambda.
Trong onDispose, hãy thêm removeOnUserLeaveHintListener bằng findActivity() và truyền vào 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")}
Thêm PiP khi rời khỏi ứng dụng cho phiên bản Android 12 trở lên
Sau Android 12, PictureInPictureParams.Builder được thêm thông qua một đối tượng sửa đổi được truyền đến trình phát video của ứng dụng.
Tạo một modifier và gọi onGloballyPositioned trên đó. Toạ độ bố cục sẽ được sử dụng ở bước sau.
Tạo một biến cho PictureInPictureParams.Builder().
Thêm câu lệnh if để kiểm tra xem SDK có phải là S trở lên hay không. Nếu có, hãy thêm setAutoEnterEnabled vào trình tạo và đặt thành true để chuyển sang chế độ PiP khi vuốt. Điều này giúp ảnh động mượt mà hơn so với việc sử dụng enterPictureInPictureMode.
Sử dụng findActivity() để gọi setPictureInPictureParams(). Gọi build() trên builder rồi truyền vào.
Sử dụng setAspectRatio để đặt tỷ lệ khung hình của cửa sổ PiP
Để đặt tỷ lệ khung hình của cửa sổ PiP, bạn có thể chọn một tỷ lệ khung hình cụ thể hoặc sử dụng chiều rộng và chiều cao của kích thước video của trình phát. Nếu bạn đang sử dụng trình phát media3, hãy kiểm tra để đảm bảo trình phát không có giá trị rỗng và kích thước video của trình phát không bằng [VideoSize.UNKNOWN][6] trước khi đặt tỷ lệ khung hình.
Nếu bạn đang sử dụng trình phát tuỳ chỉnh, hãy đặt tỷ lệ khung hình trên chiều cao và chiều rộng của trình phát bằng cách sử dụng cú pháp dành riêng cho trình phát của bạn. Xin lưu ý rằng nếu trình phát của bạn đổi kích thước trong quá trình khởi chạy, nếu kích thước đó nằm ngoài giới hạn hợp lệ của tỷ lệ khung hình, thì ứng dụng của bạn sẽ gặp sự cố. Bạn có thể cần thêm các bước kiểm tra về thời điểm có thể tính tỷ lệ khung hình, tương tự như cách thực hiện đối với trình phát media3.
Nội dung và mã mẫu trên trang này phải tuân thủ các giấy phép như mô tả trong phần Giấy phép nội dung. Java và OpenJDK là nhãn hiệu hoặc nhãn hiệu đã đăng ký của Oracle và/hoặc đơn vị liên kết của Oracle.
Cập nhật lần gần đây nhất: 2025-08-27 UTC.
[[["Dễ hiểu","easyToUnderstand","thumb-up"],["Giúp tôi giải quyết được vấn đề","solvedMyProblem","thumb-up"],["Khác","otherUp","thumb-up"]],[["Thiếu thông tin tôi cần","missingTheInformationINeed","thumb-down"],["Quá phức tạp/quá nhiều bước","tooComplicatedTooManySteps","thumb-down"],["Đã lỗi thời","outOfDate","thumb-down"],["Vấn đề về bản dịch","translationIssue","thumb-down"],["Vấn đề về mẫu/mã","samplesCodeIssue","thumb-down"],["Khác","otherDown","thumb-down"]],["Cập nhật lần gần đây nhất: 2025-08-27 UTC."],[],[],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."]]