Trong thẻ hoạt động của tệp AndroidManifest.xml
, hãy làm như sau:
- Thêm
supportsPictureInPicture
và đặt thànhtrue
để khai báo rằng bạn sẽ sử dụng tính năng PiP trong ứng dụng. Thêm
configChanges
và đặt thànhorientation|screenLayout|screenSize|smallestScreenSize
để chỉ định rằng hoạt động của bạn xử lý các thay đổi về cấu hình bố cục. Bằng cách này, hoạt động của bạn sẽ không chạy lại khi các thay đổi về bố cục xảy ra trong quá trình chuyển đổi chế độ PiP.<activity android:name=".SnippetsActivity" android:exported="true" android:supportsPictureInPicture="true" android:configChanges="orientation|screenLayout|screenSize|smallestScreenSize" android:theme="@style/Theme.Snippets">
Trong mã Compose, hãy làm như sau:
- Thêm tiện ích này trên
Context
. Bạn sẽ sử dụng tiện ích này nhiều lần trong suốt hướng dẫn để truy cập vào hoạt động.internal fun Context.findActivity(): ComponentActivity { var context = this while (context is ContextWrapper) { if (context is ComponentActivity) return context context = context.baseContext } throw IllegalStateException("Picture in picture should be called in the context of an Activity") }
Thêm PiP khi rời khỏi ứng dụng cho phiên bản Android trước 12
Để thêm PiP cho các phiên bản Android trước 12, hãy sử dụng addOnUserLeaveHintProvider
. Làm theo các bước sau để thêm PiP cho các phiên bản Android trước Android 12:
- Thêm một cổng phiên bản để mã này chỉ được truy cập trong các phiên bản O cho đến R.
- Sử dụng
DisposableEffect
vớiContext
làm khoá. - Bên trong
DisposableEffect
, hãy xác định hành vi cho thời điểm kích hoạtonUserLeaveHintProvider
bằng cách sử dụng lambda. Trong hàm lambda, hãy gọienterPictureInPictureMode()
trênfindActivity()
và truyền vàoPictureInPictureParams.Builder().build()
. - Thêm
addOnUserLeaveHintListener
bằngfindActivity()
và truyền vào lambda. - Trong
onDispose
, hãy thêmremoveOnUserLeaveHintListener
bằngfindActivity()
và truyền vào lambda.
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 = { 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") }
Thêm PiP khi rời khỏi ứng dụng cho phiên bản Android 12 trở lên
Sau Android 12, PictureInPictureParams.Builder
được thêm thông qua một đối tượng sửa đổi được truyền đến trình phát video của ứng dụng.
- Tạo một
modifier
và gọionGloballyPositioned
trên đó. Toạ độ bố cục sẽ được sử dụng ở bước sau. - Tạo một biến cho
PictureInPictureParams.Builder()
. - Thêm câu lệnh
if
để kiểm tra xem SDK có phải là S trở lên hay không. Nếu có, hãy thêmsetAutoEnterEnabled
vào trình tạo và đặt thànhtrue
để chuyển sang chế độ PiP khi vuốt. Điều này giúp ảnh động mượt mà hơn so với việc sử dụngenterPictureInPictureMode
. - Sử dụng
findActivity()
để gọisetPictureInPictureParams()
. Gọibuild()
trênbuilder
rồi truyền vào.
val pipModifier = modifier.onGloballyPositioned { layoutCoordinates -> val builder = PictureInPictureParams.Builder() if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { builder.setAutoEnterEnabled(true) } context.findActivity().setPictureInPictureParams(builder.build()) } VideoPlayer(pipModifier)
Sử dụng setAspectRatio
để đặt tỷ lệ khung hình của cửa sổ PiP
Để đặt tỷ lệ khung hình của cửa sổ PiP, bạn có thể chọn một tỷ lệ khung hình cụ thể hoặc sử dụng chiều rộng và chiều cao của kích thước video của trình phát. Nếu bạn đang sử dụng trình phát media3, hãy kiểm tra để đảm bảo trình phát không có giá trị rỗng và kích thước video của trình phát không bằng [VideoSize.UNKNOWN
][6] trước khi đặt tỷ lệ khung hình.
val context = LocalContext.current val pipModifier = modifier.onGloballyPositioned { layoutCoordinates -> val builder = PictureInPictureParams.Builder() if (shouldEnterPipMode && player != null && player.videoSize != VideoSize.UNKNOWN) { val sourceRect = layoutCoordinates.boundsInWindow().toAndroidRectF().toRect() builder.setSourceRectHint(sourceRect) builder.setAspectRatio( Rational(player.videoSize.width, player.videoSize.height) ) } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { builder.setAutoEnterEnabled(shouldEnterPipMode) } context.findActivity().setPictureInPictureParams(builder.build()) } VideoPlayer(pipModifier)
Nếu bạn đang sử dụng trình phát tuỳ chỉnh, hãy đặt tỷ lệ khung hình trên chiều cao và chiều rộng của trình phát bằng cách sử dụng cú pháp dành riêng cho trình phát của bạn. Xin lưu ý rằng nếu trình phát của bạn đổi kích thước trong quá trình khởi chạy, nếu kích thước đó nằm ngoài giới hạn hợp lệ của tỷ lệ khung hình, thì ứng dụng của bạn sẽ gặp sự cố. Bạn có thể cần thêm các bước kiểm tra về thời điểm có thể tính tỷ lệ khung hình, tương tự như cách thực hiện đối với trình phát media3.