在正確時間輸入 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)