在用于定义 OnUserLeaveHintListener 触发时的行为的 lambda 中,在对 enterPictureInPictureMode() 的调用周围添加包含状态变量的 if 语句:
valcurrentShouldEnterPipModebyrememberUpdatedState(newValue=shouldEnterPipMode)if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.O&&
Build.VERSION.SDK_INT < Build.VERSION_CODES.S){valcontext=LocalContext.currentDisposableEffect(context){valonUserLeaveBehavior:()->Unit={if(currentShouldEnterPipMode){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")}
valpipModifier=modifier.onGloballyPositioned{layoutCoordinates->
valbuilder=PictureInPictureParams.Builder()// Add autoEnterEnabled for versions S and upif(Build.VERSION.SDK_INT>=Build.VERSION_CODES.S){builder.setAutoEnterEnabled(shouldEnterPipMode)}context.findActivity().setPictureInPictureParams(builder.build())}VideoPlayer(pipModifier)
[null,null,["最后更新时间 (UTC):2025-08-23。"],[],[],null,["# Enter PiP at correct times\n\nYour app should not enter PiP mode in the following situations:\n\n- If the video is stopped or paused.\n- If you are on a different page of the app than the video player.\n\nTo control when your app enters PiP mode, add a variable that tracks the state\nof the video player using a [`mutableStateOf`](/reference/kotlin/androidx/compose/runtime/package-summary#mutableStateOf(kotlin.Any,androidx.compose.runtime.SnapshotMutationPolicy)).\n\nToggle state based on if video is playing\n-----------------------------------------\n\nTo toggle the state based on if the video player is playing, add a listener on\nthe video player. Toggle the state of your state variable based on if the player\nis playing or not:\n\n\n```kotlin\nplayer.addListener(object : Player.Listener {\n override fun onIsPlayingChanged(isPlaying: Boolean) {\n shouldEnterPipMode = isPlaying\n }\n})https://github.com/android/snippets/blob/dd30aee903e8c247786c064faab1a9ca8d10b46e/compose/snippets/src/main/java/com/example/compose/snippets/pictureinpicture/PictureInPictureSnippets.kt#L171-L175\n```\n\n\u003cbr /\u003e\n\nToggle state based on if player is released\n-------------------------------------------\n\nWhen the player is released, set your state variable to `false`:\n\n\n```kotlin\nfun releasePlayer() {\n shouldEnterPipMode = false\n}https://github.com/android/snippets/blob/dd30aee903e8c247786c064faab1a9ca8d10b46e/compose/snippets/src/main/java/com/example/compose/snippets/pictureinpicture/PictureInPictureSnippets.kt#L180-L182\n```\n\n\u003cbr /\u003e\n\nUse state to define if PiP mode is entered (pre-Android 12)\n-----------------------------------------------------------\n\n1. Since adding PiP pre-12 uses a [`DisposableEffect`](/develop/ui/compose/side-effects#disposableeffect), you need to create a new variable by [`rememberUpdatedState`](/develop/ui/compose/side-effects#rememberupdatedstate) with `newValue` set as your state variable. This will ensure that the updated version is used within the `DisposableEffect`.\n2. In the lambda that defines the behavior when the `OnUserLeaveHintListener`\n is triggered, add an `if` statement with the state variable around the call to\n `enterPictureInPictureMode()`:\n\n\n ```kotlin\n val currentShouldEnterPipMode by rememberUpdatedState(newValue = shouldEnterPipMode)\n if (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 if (currentShouldEnterPipMode) {\n context.findActivity()\n .enterPictureInPictureMode(PictureInPictureParams.Builder().build())\n }\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/dd30aee903e8c247786c064faab1a9ca8d10b46e/compose/snippets/src/main/java/com/example/compose/snippets/pictureinpicture/PictureInPictureSnippets.kt#L381-L404\n ```\n\n \u003cbr /\u003e\n\nUse state to define if PiP mode is entered (post-Android 12)\n------------------------------------------------------------\n\nPass your state variable into `setAutoEnterEnabled` so that your app only enters\nPiP mode at the right time:\n\n\n```kotlin\nval pipModifier = modifier.onGloballyPositioned { layoutCoordinates -\u003e\n val builder = PictureInPictureParams.Builder()\n\n // Add autoEnterEnabled for versions S and up\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/dd30aee903e8c247786c064faab1a9ca8d10b46e/compose/snippets/src/main/java/com/example/compose/snippets/pictureinpicture/PictureInPictureSnippets.kt#L194-L204\n```\n\n\u003cbr /\u003e\n\nUse `setSourceRectHint` to implement a smooth animation\n-------------------------------------------------------\n\nThe [`setSourceRectHint`](/reference/android/app/PictureInPictureParams.Builder#setSourceRectHint(android.graphics.Rect)) API creates a smoother animation for entering PiP\nmode. In Android 12+, it also creates a smoother animation for exiting PiP mode.\nAdd this API to the PiP builder to indicate the area of the activity that is\nvisible following the transition into PiP.\n\n1. Only add `setSourceRectHint()` to the `builder` if the state defines that the app should enter PiP mode. This avoids calculating `sourceRect` when the app does not need to enter PiP.\n2. To set the `sourceRect` value, use the `layoutCoordinates` that are given from the [`onGloballyPositioned`](/reference/kotlin/androidx/compose/ui/layout/OnGloballyPositionedModifier) function on the modifier.\n3. Call `setSourceRectHint()` on the `builder` and pass in the `sourceRect` variable.\n\n\n```kotlin\nval context = LocalContext.current\n\nval pipModifier = modifier.onGloballyPositioned { layoutCoordinates -\u003e\n val builder = PictureInPictureParams.Builder()\n if (shouldEnterPipMode) {\n val sourceRect = layoutCoordinates.boundsInWindow().toAndroidRectF().toRect()\n builder.setSourceRectHint(sourceRect)\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/dd30aee903e8c247786c064faab1a9ca8d10b46e/compose/snippets/src/main/java/com/example/compose/snippets/pictureinpicture/PictureInPictureSnippets.kt#L218-L233\n```\n\n\u003cbr /\u003e\n\n| **Note:** Depending on the video player you are using, you may need to reference the documentation and choose the `sourceRectHint` that represents the actual video content instead of the full video player."]]