Siapkan aplikasi untuk PiP

Di tag aktivitas file AndroidManifest.xml, lakukan hal berikut:

  1. Tambahkan supportsPictureInPicture dan tetapkan ke true untuk mendeklarasikan bahwa Anda akan menggunakan PiP di aplikasi.
  2. Tambahkan configChanges dan tetapkan ke orientation|screenLayout|screenSize|smallestScreenSize untuk menentukan bahwa aktivitas Anda menangani perubahan konfigurasi tata letak. Dengan cara ini, aktivitas Anda tidak akan diluncurkan kembali saat perubahan tata letak terjadi selama transisi mode PiP.

      <activity
        android:name=".SnippetsActivity"
        android:exported="true"
        android:supportsPictureInPicture="true"
        android:configChanges="orientation|screenLayout|screenSize|smallestScreenSize"
        android:theme="@style/Theme.Snippets">

Dalam kode Compose, lakukan hal berikut:

  1. Tambahkan ekstensi ini di Context. Anda akan menggunakan ekstensi ini beberapa kali sepanjang panduan untuk mengakses aktivitas.
    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")
    }

Menambahkan PiP di aplikasi pergi untuk versi Android sebelum 12

Untuk menambahkan PiP untuk pra-Android 12, gunakan addOnUserLeaveHintProvider. Ikuti langkah-langkah berikut untuk menambahkan PiP untuk versi Android sebelum 12:

  1. Tambahkan gate versi sehingga kode ini hanya diakses dalam versi O hingga R.
  2. Gunakan DisposableEffect dengan Context sebagai kuncinya.
  3. Di dalam DisposableEffect, tentukan perilaku saat onUserLeaveHintProvider dipicu menggunakan lambda. Di lambda, panggil enterPictureInPictureMode() di findActivity() dan teruskan PictureInPictureParams.Builder().build().
  4. Tambahkan addOnUserLeaveHintListener menggunakan findActivity() dan teruskan lambda.
  5. Di onDispose, tambahkan removeOnUserLeaveHintListener menggunakan findActivity() dan teruskan 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")
}

Menambahkan PiP di aplikasi pergi untuk versi Android setelah 12

Setelah Android 12, PictureInPictureParams.Builder ditambahkan melalui pengubah yang diteruskan ke pemutar video aplikasi.

  1. Buat modifier dan panggil onGloballyPositioned di dalamnya. Koordinat tata letak akan digunakan di langkah berikutnya.
  2. Buat variabel untuk PictureInPictureParams.Builder().
  3. Tambahkan pernyataan if untuk memeriksa apakah SDK adalah S atau yang lebih baru. Jika ya, tambahkan setAutoEnterEnabled ke builder dan tetapkan ke true untuk memasuki mode PiP saat menggeser. Hal ini memberikan animasi yang lebih lancar daripada melalui enterPictureInPictureMode.
  4. Gunakan findActivity() untuk memanggil setPictureInPictureParams(). Panggil build() pada builder dan teruskan.

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)

Menggunakan setAspectRatio untuk menetapkan rasio aspek jendela PiP

Untuk menetapkan rasio aspek jendela PiP, Anda dapat memilih rasio aspek tertentu atau menggunakan lebar dan tinggi ukuran video pemutar. Jika Anda menggunakan pemutar media3, pastikan pemutar bukan null dan ukuran video pemutar tidak sama dengan [VideoSize.UNKNOWN][6] sebelum menetapkan rasio aspek.

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)

Jika Anda menggunakan pemutar kustom, tetapkan rasio aspek pada tinggi dan lebar pemutar menggunakan sintaksis khusus untuk pemutar Anda. Perhatikan bahwa jika pemutar mengubah ukuran selama inisialisasi, jika berada di luar batas yang valid dari rasio aspek yang dapat digunakan, aplikasi Anda akan error. Anda mungkin perlu menambahkan pemeriksaan saat rasio aspek dapat dihitung, mirip dengan cara yang dilakukan untuk pemutar media3.