ตั้งค่าแอปสำหรับ PIP

ในแท็กกิจกรรมของไฟล์ AndroidManifest.xml ให้ทําดังนี้

  1. เพิ่ม supportsPictureInPicture แล้วตั้งค่าเป็น true เพื่อประกาศว่าคุณจะใช้ PiP ในแอป
  2. เพิ่ม configChanges แล้วตั้งค่าเป็น orientation|screenLayout|screenSize|smallestScreenSize เพื่อระบุว่ากิจกรรมของคุณจัดการการเปลี่ยนแปลงการกําหนดค่าเลย์เอาต์ วิธีนี้จะทำให้กิจกรรมไม่เปิดขึ้นมาใหม่เมื่อมีการเปลี่ยนแปลงเลย์เอาต์ระหว่างการเปลี่ยนโหมด PIP

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

ในโค้ดการเขียน ให้ทําดังนี้

  1. เพิ่มส่วนขยายนี้ใน Context คุณจะใช้ส่วนขยายนี้หลายครั้งตลอดทั้งคู่มือเพื่อเข้าถึงกิจกรรม
    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")
    }

เพิ่ม PiP ในแอปที่หยุดอยู่สำหรับเวอร์ชันก่อน Android 12

หากต้องการเพิ่ม PiP สำหรับ Android ก่อนเวอร์ชัน 12 ให้ใช้ addOnUserLeaveHintProvider ทําตามขั้นตอนเหล่านี้เพื่อเพิ่ม PiP สําหรับเวอร์ชันก่อน Android 12

  1. เพิ่มประตูเวอร์ชันเพื่อให้เข้าถึงรหัสนี้ได้เฉพาะในเวอร์ชัน O ถึง R
  2. ใช้ DisposableEffect ที่มี Context เป็นคีย์
  3. ภายใน DisposableEffect ให้กําหนดลักษณะการทํางานเมื่อมีการเรียกใช้ onUserLeaveHintProvider โดยใช้ Lambda ใน Lambda ให้เรียกใช้ enterPictureInPictureMode() ใน findActivity() และส่ง PictureInPictureParams.Builder().build()
  4. เพิ่ม addOnUserLeaveHintListener โดยใช้ findActivity() แล้วส่งค่า Lambda
  5. ใน onDispose ให้เพิ่ม removeOnUserLeaveHintListener โดยใช้ findActivity() และส่งค่า 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")
}

เพิ่ม PiP ในแอปที่หยุดอยู่สำหรับ Android เวอร์ชันหลัง 12

หลังจาก Android 12 ระบบจะเพิ่ม PictureInPictureParams.Builder ผ่านตัวแก้ไขที่ส่งไปยังโปรแกรมเล่นวิดีโอของแอป

  1. สร้าง modifier แล้วเรียกใช้ onGloballyPositioned ใน modifier ระบบจะใช้พิกัดเลย์เอาต์ในขั้นตอนถัดไป
  2. สร้างตัวแปรสําหรับ PictureInPictureParams.Builder()
  3. เพิ่มคำสั่ง if เพื่อตรวจสอบว่า SDK เป็น S ขึ้นไปหรือไม่ หากใช่ ให้เพิ่ม setAutoEnterEnabled ลงในเครื่องมือสร้าง แล้วตั้งค่าเป็น true เพื่อเข้าสู่โหมด PiP เมื่อปัด วิธีนี้จะทำให้ภาพเคลื่อนไหวราบรื่นกว่าการผ่าน enterPictureInPictureMode
  4. ใช้ findActivity() เพื่อโทรหา setPictureInPictureParams() โทรหา build() ใน builder แล้วส่งต่อ

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)

ใช้ setAspectRatio เพื่อตั้งค่าสัดส่วนภาพของหน้าต่าง PiP

หากต้องการตั้งค่าสัดส่วนภาพของหน้าต่าง PiP คุณสามารถเลือกสัดส่วนภาพที่ต้องการหรือจะใช้ความกว้างและความสูงของขนาดวิดีโอของโปรแกรมเล่นก็ได้ หากคุณใช้โปรแกรมเล่น media3 ให้ตรวจสอบว่าโปรแกรมเล่นไม่ใช่ค่า Null และขนาดวิดีโอของโปรแกรมเล่นไม่เท่ากับ [VideoSize.UNKNOWN][6] ก่อนตั้งค่าสัดส่วนการแสดงผล

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)

หากคุณใช้เพลเยอร์ที่กำหนดเอง ให้ตั้งค่าสัดส่วนภาพตามความสูงและความกว้างของเพลเยอร์โดยใช้ไวยากรณ์เฉพาะสำหรับเพลเยอร์ โปรดทราบว่าหากวิดีโอเพลเยอร์ปรับขนาดระหว่างการเริ่มต้น หากวิดีโอเพลเยอร์อยู่นอกขอบเขตที่ยอมรับได้ของอัตราส่วนภาพ แอปจะขัดข้อง คุณอาจต้องเพิ่มการตรวจสอบเมื่อสามารถคํานวณสัดส่วนภาพได้ ซึ่งคล้ายกับการตรวจสอบสําหรับโปรแกรมเล่นสื่อ