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:

  • Nếu video đang 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 của bạn 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 vào trình phát video. Bật/tắt 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
    }
})

Bật/tắt trạng thái dựa trên việc người chơi có được thả hay không

Khi phát hành trình phát, 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ó chuyển sang 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, trong đó 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 với 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: () -> 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")
    }

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

Truyền biến trạng thái vào setAutoEnterEnabled để ứng dụng của bạn chỉ chuyển sang chế độ PiP 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 để triển khai ả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, tính năng này cũng tạo ra ả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)