Chuyển sang chế độ PiP vào đúng thời điểm

Ứng dụng của bạn không được chuyển sang chế độ PiP trong các trường hợp sau:

  • Video bị dừng hoặc tạm dừng.
  • Nếu bạn đang ở một trang khác của ứng dụng chứ không phải trình phát video.

Để kiểm soát thời điểm ứng dụng chuyển sang chế độ PiP, hãy thêm một biến theo dõi trạng thái của trình phát video bằng mutableStateOf.

Bật/tắt trạng thái dựa trên việc video có đang phát hay không

Để bật/tắt trạng thái dựa trên việc trình phát video có đang phát hay không, hãy thêm trình nghe trên trình phát video. Chuyển đổi trạng thái của biến trạng thái dựa trên việc người chơi có đang chơi hay không:

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

Chuyển đổi trạng thái dựa trên việc trình phát có được phát hành hay không

Khi trình phát được giải phóng, hãy đặt biến trạng thái thành false:

fun releasePlayer() {
    shouldEnterPipMode = false
}

Sử dụng trạng thái để xác định xem có vào chế độ PiP hay không (trước Android 12)

  1. Vì việc thêm PiP trước phiên bản 12 sử dụng DisposableEffect, nên bạn cần tạo một biến mới bằng rememberUpdatedState với newValue được đặt làm biến trạng thái. Điều này sẽ đảm bảo rằng phiên bản cập nhật được sử dụng trong DisposableEffect.
  2. Trong hàm lambda xác định hành vi khi OnUserLeaveHintListener được kích hoạt, hãy thêm câu lệnh if có biến trạng thái xung quanh lệnh gọi đến enterPictureInPictureMode():

    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")
    }

Sử dụng trạng thái để xác định xem có vào chế độ PiP hay không (sau Android 12)

Truyền biến trạng thái vào setAutoEnterEnabled để ứng dụng chỉ chuyển sang chế độ Hình trong hình vào đúng thời điểm:

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)

Sử dụng setSourceRectHint để có ảnh động mượt mà

API setSourceRectHint tạo ảnh động mượt mà hơn khi chuyển sang chế độ PiP. Trên Android 12 trở lên, cờ này cũng tạo ảnh động mượt mà hơn khi thoát khỏi chế độ PiP. Thêm API này vào trình tạo PiP để cho biết khu vực của hoạt động hiển thị sau khi chuyển đổi sang PiP.

  1. Chỉ thêm setSourceRectHint() vào builder nếu trạng thái xác định rằng ứng dụng sẽ chuyển sang chế độ PiP. Điều này giúp tránh tính toán sourceRect khi ứng dụng không cần chuyển sang chế độ PiP.
  2. Để đặt giá trị sourceRect, hãy sử dụng layoutCoordinates được cung cấp từ hàm onGloballyPositioned trên đối tượng sửa đổi.
  3. Gọi setSourceRectHint() trên builder và truyền vào biến 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)