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