在正確時間輸入 PiP

在下列情況下,應用程式不應進入子母畫面模式:

  • 影片是否已停止或暫停。
  • 如果應用程式顯示的不是影片播放器頁面。

如要控制應用程式進入子母畫面模式的時機,請使用 mutableStateOf 新增變數,追蹤影片播放器的狀態。

根據影片是否正在播放切換狀態

如要根據影片播放器是否正在播放影片切換狀態,請在影片播放器上新增監聽器。根據播放器是否正在播放內容,切換狀態變數的狀態:

player.addListener(object : Player.Listener {
    override fun onIsPlayingChanged(isPlaying: Boolean) {
        shouldEnterPipMode = isPlaying
    }
})

根據是否已釋放播放器,切換狀態

當播放器釋出時,請將狀態變數設為 false:

fun releasePlayer() {
    shouldEnterPipMode = false
}

使用狀態定義是否進入子母畫面模式 (Android 12 之前的版本)

  1. 由於在 Android 12 之前的版本中新增子母畫面模式時會使用 DisposableEffect,因此您需要透過 rememberUpdatedState 建立新變數,並將 newValue 設為狀態變數。這樣可確保 DisposableEffect 內使用的是更新後的版本。
  2. 在定義 OnUserLeaveHintListener 觸發時行為的 lambda 中,請在呼叫 enterPictureInPictureMode() 的前後加上含有狀態變數的 if 陳述式:

    val currentShouldEnterPipMode by rememberUpdatedState(newValue = shouldEnterPipMode)
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O &&
        Build.VERSION.SDK_INT < Build.VERSION_CODES.S
    ) {
        val context = LocalContext.current
        DisposableEffect(context) {
            val onUserLeaveBehavior = Runnable {
                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")
    }

使用狀態定義是否進入子母畫面模式 (Android 12 以上版本)

將狀態變數傳遞至 setAutoEnterEnabled,確保應用程式只會在適當時間進入子母畫面模式:

val pipModifier = modifier.onGloballyPositioned { layoutCoordinates ->
    val builder = PictureInPictureParams.Builder()

    // Add autoEnterEnabled for versions S and up
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
        builder.setAutoEnterEnabled(shouldEnterPipMode)
    }
    context.findActivity().setPictureInPictureParams(builder.build())
}

VideoPlayer(pipModifier)

使用 setSourceRectHint 製作流暢動畫

setSourceRectHint API 可建立更流暢的動畫,讓使用者進入子母畫面模式。在 Android 12 以上版本中,系統也會在結束子母畫面模式時,建立更流暢的動畫。將這個 API 新增至子母畫面建構工具,指出活動在轉換為子母畫面後可見的區域。

  1. 只有在狀態定義應用程式應進入子母畫面模式時,才將 setSourceRectHint() 新增至 builder。這樣可避免在應用程式不需要進入子母畫面模式時計算 sourceRect。
  2. 如要設定 sourceRect 值,請使用修飾符的 onGloballyPositioned 函式提供的 layoutCoordinates。
  3. 在 builder 上呼叫 setSourceRectHint(),並傳入 sourceRect 變數。

val context = LocalContext.current

val pipModifier = modifier.onGloballyPositioned { layoutCoordinates ->
    val builder = PictureInPictureParams.Builder()
    if (shouldEnterPipMode) {
        val sourceRect = layoutCoordinates.boundsInWindow().toAndroidRectF().toRect()
        builder.setSourceRectHint(sourceRect)
    }

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
        builder.setAutoEnterEnabled(shouldEnterPipMode)
    }
    context.findActivity().setPictureInPictureParams(builder.build())
}

VideoPlayer(pipModifier)