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

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

  • Nếu 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 cách sử dụng mutableStateOf.

Chuyển đổi trạng thái dựa trên việc video có đang phát hay không

Để chuyển đổi 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 một trình nghe vào 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 phát 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 chế độ PiP có được bật 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 dùng trong DisposableEffect.
  2. Trong lambda xác định hành vi khi OnUserLeaveHintListener được kích hoạt, hãy thêm một 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 chế độ PiP có được kích hoạt 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 để tạo ảnh động mượt mà

API setSourceRectHint tạo ra một ảnh động mượt mà hơn khi chuyển sang chế độ PiP. Trên Android 12 trở lên, thao tác này cũng tạo ra một ả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 vùng hoạt động hiển thị sau khi chuyển sang chế độ 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 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 rồi 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)