ใช้การแสดงภาพซ้อนภาพ (PIP)

ลองใช้วิธีแบบ Compose
Jetpack Compose เป็นชุดเครื่องมือ UI ที่แนะนำสำหรับ Android ดูวิธีรองรับการแสดงภาพซ้อนภาพใน Compose

เริ่มตั้งแต่ Android 8.0 (ระดับ API 26) เป็นต้นไป Android อนุญาตให้กิจกรรมเปิดตัวในโหมดการแสดงภาพซ้อนภาพ (PIP) PIP เป็นโหมดหลายหน้าต่างประเภทพิเศษที่ใช้สำหรับการเล่นวิดีโอ วิดีโอคอล และการนำทาง โดยจะช่วยให้ผู้ใช้ปักหมุดหน้าต่างกิจกรรมที่มีอยู่ไว้ที่มุมของหน้าจอในระหว่างที่ไปยังแอปต่างๆ หรือเลือกดูเนื้อหาบนหน้าจอหลัก

PIP ใช้ประโยชน์จาก API หลายหน้าต่างที่พร้อมใช้งานใน Android 7.0 เพื่อแสดงหน้าต่างวิดีโอแบบวางซ้อนที่ปักหมุดไว้ หากต้องการเพิ่ม PIP ในแอป คุณต้องลงทะเบียนกิจกรรมที่รองรับ PIP เปลี่ยนกิจกรรมเป็นโหมด PIP ตามความจำเป็น และตรวจสอบว่าไม่ได้แสดงองค์ประกอบของ UI อยู่และวิดีโอจะเล่นต่อเมื่อกิจกรรมอยู่ในโหมด PIP

หน้าต่าง PIP จะปรากฏในเลเยอร์บนสุดของหน้าจอที่มุมซึ่งระบบเลือกไว้

นอกจากนี้ PIP ยังรองรับในอุปกรณ์ระบบปฏิบัติการ Android TV ที่เข้ากันได้ซึ่งใช้ Android 14 (ระดับ API 34) ขึ้นไป แม้ว่าจะมีหลายสิ่งที่คล้ายกัน แต่ก็มี ข้อควรพิจารณาเพิ่มเติมเมื่อใช้ PIP บนทีวี

วิธีที่ผู้ใช้โต้ตอบกับหน้าต่าง PIP

ผู้ใช้สามารถลากหน้าต่าง PIP ไปยังตำแหน่งอื่นได้ นอกจากนี้ ตั้งแต่ Android 12 เป็นต้นไป ผู้ใช้ยังทำสิ่งต่อไปนี้ได้ด้วย

  • แตะหน้าต่างครั้งเดียวเพื่อแสดงปุ่มสลับโหมดเต็มหน้าจอ ปุ่มปิด ปุ่มการตั้งค่า และการกระทำที่กำหนดเองซึ่งแอปของคุณมีให้ (เช่น ตัวควบคุมการเล่น)

  • แตะหน้าต่างสองครั้งเพื่อสลับระหว่างขนาด PIP ปัจจุบันกับขนาด PIP สูงสุดหรือต่ำสุด เช่น การแตะหน้าต่างที่ขยายใหญ่สุดสองครั้งจะย่อหน้าต่างนั้นให้เล็กลง และในทางกลับกันก็เช่นกัน

  • ซ่อนหน้าต่างโดยการลากไปที่ขอบซ้ายหรือขวา หากต้องการเลิกซ่อนหน้าต่าง ให้แตะส่วนที่มองเห็นได้ของหน้าต่างที่ซ่อนไว้หรือลากหน้าต่างนั้นออกมา

  • ปรับขนาดหน้าต่าง PIP โดยใช้การบีบเพื่อซูม

แอปของคุณจะควบคุมเวลาที่กิจกรรมปัจจุบันเข้าสู่โหมด PIP ตัวอย่างเช่น

  • กิจกรรมสามารถเข้าสู่โหมด PIP ได้เมื่อผู้ใช้แตะปุ่มหน้าแรกหรือปัดขึ้นไปที่หน้าแรก วิธีนี้ช่วยให้ Google Maps แสดงเส้นทางต่อไปได้ในขณะที่ผู้ใช้ทำกิจกรรมอื่นไปพร้อมกัน

  • แอปของคุณสามารถย้ายวิดีโอเข้าสู่โหมด PIP ได้เมื่อผู้ใช้กลับจากวิดีโอเพื่อเลือกดูเนื้อหาอื่นๆ

  • แอปของคุณสามารถเปลี่ยนวิดีโอเป็นโหมด PIP ได้ขณะที่ผู้ใช้ดูตอนจบของเนื้อหา หน้าจอหลักจะแสดงข้อมูลโปรโมตหรือข้อมูลสรุปเกี่ยวกับตอนถัดไปในซีรีส์

  • แอปของคุณสามารถให้วิธีแก่ผู้ใช้ในการจัดคิวเนื้อหาเพิ่มเติมขณะที่ดูวิดีโอ วิดีโอจะเล่นต่อในโหมด PIP ขณะที่หน้าจอหลักแสดงกิจกรรมการเลือกเนื้อหา

ประกาศการรองรับ PIP

โดยค่าเริ่มต้น ระบบจะไม่รองรับ PIP สำหรับแอปโดยอัตโนมัติ หากต้องการรองรับ PIP ในแอป ให้ลงทะเบียนกิจกรรมวิดีโอในไฟล์ Manifest โดยตั้งค่า android:supportsPictureInPicture เป็น true นอกจากนี้ ให้ระบุว่ากิจกรรมของคุณจัดการการเปลี่ยนแปลงการกำหนดค่าเลย์เอาต์ได้ เพื่อไม่ให้กิจกรรมรีสตาร์ทเมื่อมีการเปลี่ยนแปลงเลย์เอาต์ระหว่างการเปลี่ยนโหมด PIP

<activity android:name="VideoActivity"
    android:supportsPictureInPicture="true"
    android:configChanges=
        "screenSize|smallestScreenSize|screenLayout|orientation"
    ...

ใช้ PIP ด้วย Jetpack

ใช้ไลบรารีการแสดงภาพซ้อนภาพของ Jetpack เพื่อใช้ ประสบการณ์การแสดงภาพซ้อนภาพ เนื่องจากจะช่วยเพิ่มความคล่องตัวในการผสานรวมและลดปัญหาทั่วไป ในแอป ดูตัวอย่างการใช้งานได้ในแอปตัวอย่างของแพลตฟอร์ม อย่างไรก็ตาม หากต้องการใช้ PIP โดยใช้ API ของแพลตฟอร์ม โปรดดูเอกสารประกอบต่อไปนี้

เปลี่ยนกิจกรรมเป็น PIP

ตั้งแต่ Android 12 เป็นต้นไป คุณสามารถเปลี่ยนกิจกรรมเป็นโหมด PIP ได้โดยตั้งค่า แฟล็ก setAutoEnterEnabled เป็น true การตั้งค่านี้จะทำให้กิจกรรม เปลี่ยนเป็นโหมด PIP โดยอัตโนมัติตามความจำเป็นโดยไม่ต้องเรียกใช้ enterPictureInPictureMode() ใน onUserLeaveHint และยังช่วยให้การเปลี่ยนโหมดเป็นไปอย่างราบรื่นยิ่งขึ้นด้วย ดูรายละเอียดได้ที่หัวข้อ ทำให้การเปลี่ยนไปใช้โหมด PIP จากการไปยังส่วนต่างๆ ด้วยท่าทางสัมผัสราบรื่นยิ่งขึ้น

หากกำหนดเป้าหมายเป็น Android 11 หรือต่ำกว่า กิจกรรมต้องเรียกใช้ enterPictureInPictureMode() เพื่อเปลี่ยนเป็นโหมด PIP ตัวอย่างเช่น โค้ดต่อไปนี้จะเปลี่ยนกิจกรรมเป็นโหมด PIP เมื่อผู้ใช้คลิกปุ่มเฉพาะใน UI ของแอป

Kotlin

override fun onActionClicked(action: Action) {
    if (action.id.toInt() == R.id.lb_control_picture_in_picture) {
        activity?.enterPictureInPictureMode()
        return
    }
}

Java

@Override
public void onActionClicked(Action action) {
    if (action.getId() == R.id.lb_control_picture_in_picture) {
        getActivity().enterPictureInPictureMode();
        return;
    }
    ...
}

คุณอาจต้องการใส่ตรรกะที่เปลี่ยนกิจกรรมเป็นโหมด PIP แทนที่จะย้ายไปทำงานเบื้องหลัง เช่น Google Maps จะเปลี่ยนเป็นโหมด PIP หากผู้ใช้กดปุ่มหน้าแรกหรือปุ่มแอปที่ใช้ล่าสุดขณะที่แอปกำลังนำทาง คุณสามารถ จัดการกรณีนี้ได้โดยการลบล้าง onUserLeaveHint() ดังนี้

Kotlin

override fun onUserLeaveHint() {
    if (iWantToBeInPipModeNow()) {
        enterPictureInPictureMode()
    }
}

Java

@Override
public void onUserLeaveHint () {
    if (iWantToBeInPipModeNow()) {
        enterPictureInPictureMode();
    }
}

แนะนำ: มอบประสบการณ์การเปลี่ยนไปใช้ PIP ที่ราบรื่นแก่ผู้ใช้

Android 12 ได้เพิ่มการปรับปรุงที่สำคัญในด้านความสวยงามให้กับการเปลี่ยนภาพเคลื่อนไหวระหว่างหน้าต่างแบบเต็มหน้าจอและหน้าต่าง PIP เราขอแนะนำอย่างยิ่งให้ใช้การเปลี่ยนแปลงที่เกี่ยวข้องทั้งหมด เมื่อคุณทำเช่นนั้นแล้ว การเปลี่ยนแปลงเหล่านี้จะปรับขนาดให้เข้ากับหน้าจอขนาดใหญ่ เช่น อุปกรณ์พับได้และแท็บเล็ตโดยอัตโนมัติโดยที่คุณไม่ต้องดำเนินการใดๆ เพิ่มเติม

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

การเปลี่ยนแปลงเหล่านี้เกี่ยวข้องกับสิ่งต่อไปนี้

  • ทำให้การเปลี่ยนไปใช้โหมด PIP จากการไปยังส่วนต่างๆ ด้วยท่าทางสัมผัสราบรื่นยิ่งขึ้น
  • ตั้งค่า sourceRectHint ที่เหมาะสมสำหรับการเข้าและออกจากโหมด PIP
  • ปิดใช้การปรับขนาดแบบราบรื่นสำหรับเนื้อหาที่ไม่ใช่วิดีโอ

โปรดดูตัวอย่าง Android Kotlin PictureInPicture เป็นข้อมูลอ้างอิงสำหรับการเปิดใช้ประสบการณ์การเปลี่ยนโหมดที่ราบรื่น

ทำให้การเปลี่ยนไปใช้โหมด PIP จากการไปยังส่วนต่างๆ ด้วยท่าทางสัมผัสราบรื่นยิ่งขึ้น

ตั้งแต่ Android 12 เป็นต้นไป แฟล็ก setAutoEnterEnabled จะให้ภาพเคลื่อนไหวที่ราบรื่นยิ่งขึ้นสำหรับการเปลี่ยนไปใช้เนื้อหาวิดีโอในโหมด PIP โดยใช้การนำทางด้วยท่าทาง เช่น เมื่อปัดขึ้นไปที่หน้าแรกจากโหมดเต็มหน้าจอ

ทำตามขั้นตอนต่อไปนี้เพื่อทำการเปลี่ยนแปลงนี้

  1. ใช้ setAutoEnterEnabled เพื่อสร้าง PictureInPictureParams.Builder ดังนี้

    Kotlin

    setPictureInPictureParams(PictureInPictureParams.Builder()
        .setAspectRatio(aspectRatio)
        .setSourceRectHint(sourceRectHint)
        .setAutoEnterEnabled(true)
        .build())

    Java

    setPictureInPictureParams(new PictureInPictureParams.Builder()
        .setAspectRatio(aspectRatio)
        .setSourceRectHint(sourceRectHint)
        .setAutoEnterEnabled(true)
        .build());
  2. เรียกใช้ setPictureInPictureParams ด้วยที่อัปเดตแล้ว PictureInPictureParams โดยเร็ว แอปจะไม่รอการเรียกกลับ onUserLeaveHint (ซึ่งเป็นสิ่งที่แอปจะทำใน Android 11)

    เช่น คุณอาจต้องการเรียกใช้ setPictureInPictureParams ในการเล่นครั้งแรกและครั้งต่อๆ ไปหากมีการเปลี่ยนอัตราส่วนกว้างยาว

  3. เรียกใช้ setAutoEnterEnabled(false) แต่เฉพาะเมื่อจำเป็นเท่านั้น เช่น คุณอาจไม่ต้องการเข้าสู่โหมด PIP หากการเล่นปัจจุบันอยู่ในสถานะหยุดชั่วคราว

ตั้งค่า sourceRectHint ที่เหมาะสมสำหรับการเข้าและออกจากโหมด PIP

ตั้งแต่มีการเปิดตัว PIP ใน Android 8.0 เป็นต้นมา setSourceRectHint จะระบุพื้นที่ของกิจกรรมที่มองเห็นได้หลังจากการเปลี่ยนไปใช้ การแสดงภาพซ้อนภาพ เช่น ขอบเขตของมุมมองวิดีโอในวิดีโอเพลเยอร์

ใน Android 12 ระบบจะใช้ sourceRectHint เพื่อใช้ภาพเคลื่อนไหวที่ราบรื่นยิ่งขึ้นทั้งเมื่อเข้าและออกจากโหมด PIP

วิธีตั้งค่า sourceRectHint อย่างถูกต้องสำหรับการเข้าและออกจากโหมด PIP

  1. สร้าง PictureInPictureParams โดยใช้ขอบเขตที่เหมาะสมเป็น sourceRectHint นอกจากนี้ เราขอแนะนำให้แนบ Listener การเปลี่ยนแปลงเลย์เอาต์กับวิดีโอเพลเยอร์ด้วย

    Kotlin

    val mOnLayoutChangeListener =
    OnLayoutChangeListener { v: View?, oldLeft: Int,
            oldTop: Int, oldRight: Int, oldBottom: Int, newLeft: Int, newTop:
            Int, newRight: Int, newBottom: Int ->
        val sourceRectHint = Rect()
        mYourVideoView.getGlobalVisibleRect(sourceRectHint)
        val builder = PictureInPictureParams.Builder()
            .setSourceRectHint(sourceRectHint)
        setPictureInPictureParams(builder.build())
    }
    
    mYourVideoView.addOnLayoutChangeListener(mOnLayoutChangeListener)

    Java

    private final View.OnLayoutChangeListener mOnLayoutChangeListener =
            (v, oldLeft, oldTop, oldRight, oldBottom, newLeft, newTop, newRight,
            newBottom) -> {
        final Rect sourceRectHint = new Rect();
        mYourVideoView.getGlobalVisibleRect(sourceRectHint);
        final PictureInPictureParams.Builder builder =
            new PictureInPictureParams.Builder()
                .setSourceRectHint(sourceRectHint);
        setPictureInPictureParams(builder.build());
    };
    
    mYourVideoView.addOnLayoutChangeListener(mOnLayoutChangeListener);
  2. หากจำเป็น ให้อัปเดต sourceRectHint ก่อนที่ระบบจะเริ่มการ เปลี่ยนโหมดออก เมื่อระบบกำลังจะออกจากโหมด PIP ระบบจะจัดวางลำดับชั้นการแสดงผลของกิจกรรมให้เป็นการกำหนดค่าปลายทาง (เช่น เต็มหน้าจอ) แอปสามารถแนบ Listener การเปลี่ยนแปลงเลย์เอาต์กับมุมมองรากหรือมุมมองเป้าหมาย (เช่น มุมมองวิดีโอเพลเยอร์) เพื่อตรวจหาเหตุการณ์และอัปเดต sourceRectHint ก่อนที่ภาพเคลื่อนไหวจะเริ่มขึ้น

    Kotlin

    // Listener is called immediately after the user exits PiP but before animating.
    playerView.addOnLayoutChangeListener { _, left, top, right, bottom,
                        oldLeft, oldTop, oldRight, oldBottom ->
        if (left != oldLeft
            || right != oldRight
            || top != oldTop
            || bottom != oldBottom) {
            // The playerView's bounds changed, update the source hint rect to
            // reflect its new bounds.
            val sourceRectHint = Rect()
            playerView.getGlobalVisibleRect(sourceRectHint)
            setPictureInPictureParams(
                PictureInPictureParams.Builder()
                    .setSourceRectHint(sourceRectHint)
                    .build()
            )
        }
    }

    Java

    // Listener is called right after the user exits PiP but before animating.
    playerView.addOnLayoutChangeListener((v, left, top, right, bottom,
                        oldLeft, oldTop, oldRight, oldBottom) -> {
        if (left != oldLeft
            || right != oldRight
            || top != oldTop
            || bottom != oldBottom) {
            // The playerView's bounds changed, update the source hint rect to
            // reflect its new bounds.
            final Rect sourceRectHint = new Rect();
            playerView.getGlobalVisibleRect(sourceRectHint);
            setPictureInPictureParams(
                new PictureInPictureParams.Builder()
                    .setSourceRectHint(sourceRectHint)
                    .build());
        }
    });

ปิดใช้การปรับขนาดแบบราบรื่นสำหรับเนื้อหาที่ไม่ใช่วิดีโอ

Android 12 เพิ่มแฟล็ก setSeamlessResizeEnabled ซึ่งให้ภาพเคลื่อนไหวแบบเฟดที่ราบรื่นยิ่งขึ้นเมื่อปรับขนาดเนื้อหาที่ไม่ใช่วิดีโอในหน้าต่าง PIP ก่อนหน้านี้ การปรับขนาดเนื้อหาที่ไม่ใช่วิดีโอในหน้าต่าง PIP อาจทำให้เกิดสิ่งประดิษฐ์ที่มองเห็นได้ไม่ราบรื่น

วิธีเปิดใช้การปรับขนาดแบบราบรื่นสำหรับเนื้อหาวิดีโอ

Kotlin

setPictureInPictureParams(PictureInPictureParams.Builder()
    .setSeamlessResizeEnabled(true)
    .build())

Java

setPictureInPictureParams(new PictureInPictureParams.Builder()
    .setSeamlessResizeEnabled(true)
    .build());

จัดการ UI ระหว่างการแสดงภาพซ้อนภาพ

เมื่อกิจกรรมเข้าสู่หรือออกจากโหมดการแสดงภาพซ้อนภาพ (PIP) ระบบจะเรียกใช้ Activity.onPictureInPictureModeChanged() หรือ Fragment.onPictureInPictureModeChanged()

Android 15 มีการเปลี่ยนแปลงที่ช่วยให้การเปลี่ยนโหมดราบรื่นยิ่งขึ้นเมื่อเข้าสู่โหมด PIP ซึ่งเป็นประโยชน์สำหรับแอปที่มีองค์ประกอบ UI วางซ้อนอยู่ด้านบนของ UI หลักซึ่งเข้าสู่โหมด PIP

นักพัฒนาซอฟต์แวร์ใช้การเรียกกลับ onPictureInPictureModeChanged() เพื่อกำหนดตรรกะที่สลับการมองเห็นขององค์ประกอบ UI ที่วางซ้อน การเรียกกลับนี้จะทริกเกอร์เมื่อภาพเคลื่อนไหวการเข้าสู่หรือออกจากโหมด PIP เสร็จสมบูรณ์ ตั้งแต่ Android 15 เป็นต้นไป คลาส PictureInPictureUiState จะมีสถานะใหม่

สถานะ UI ใหม่นี้จะทำให้แอปที่กำหนดเป้าหมายเป็น Android 15 สังเกตเห็นการเรียกใช้การเรียกกลับ Activity#onPictureInPictureUiStateChanged() ด้วย isTransitioningToPip() ทันทีที่ภาพเคลื่อนไหว PIP เริ่มขึ้น มีองค์ประกอบ UI หลายรายการที่ไม่เกี่ยวข้องกับแอปเมื่ออยู่ในโหมด PIP เช่น มุมมองหรือเลย์เอาต์ที่มีข้อมูลอย่างเช่น คำแนะนำ วิดีโอที่จะเล่นต่อไป การให้คะแนน และชื่อ เมื่อแอปเข้าสู่โหมด PIP ให้ใช้การเรียกกลับ onPictureInPictureUiStateChanged() เพื่อซ่อนองค์ประกอบ UI เหล่านี้ เมื่อแอปเปลี่ยนจากหน้าต่าง PIP ไปเป็นโหมดเต็มหน้าจอ ให้ใช้การเรียกกลับ onPictureInPictureModeChanged() เพื่อเลิกซ่อนองค์ประกอบเหล่านี้ ดังที่แสดงในตัวอย่างต่อไปนี้

Kotlin

override fun onPictureInPictureUiStateChanged(pipState: PictureInPictureUiState) {
        if (pipState.isTransitioningToPip()) {
          // Hide UI elements.
        }
    }

Java

@Override
public void onPictureInPictureUiStateChanged(PictureInPictureUiState pipState) {
        if (pipState.isTransitioningToPip()) {
          // Hide UI elements.
        }
    }

Kotlin

override fun onPictureInPictureModeChanged(isInPictureInPictureMode: Boolean) {
        if (isInPictureInPictureMode) {
          // Unhide UI elements.
        }
    }

Java

@Override
public void onPictureInPictureModeChanged(boolean isInPictureInPictureMode) {
        if (isInPictureInPictureMode) {
          // Unhide UI elements.
        }
    }

การสลับการมองเห็นอย่างรวดเร็วขององค์ประกอบ UI ที่ไม่เกี่ยวข้อง (สำหรับหน้าต่าง PIP) จะช่วยให้ภาพเคลื่อนไหวการเข้าสู่โหมด PIP ราบรื่นและไม่มีการกะพริบ

ลบล้างการเรียกกลับเหล่านี้เพื่อวาดองค์ประกอบ UI ของกิจกรรมใหม่ โปรดทราบว่าในโหมด PIP กิจกรรมของคุณจะแสดงในหน้าต่างขนาดเล็ก ผู้ใช้จะโต้ตอบกับองค์ประกอบ UI ของแอปไม่ได้เมื่อแอปอยู่ในโหมด PIP และรายละเอียดขององค์ประกอบ UI ขนาดเล็กอาจดูยาก กิจกรรมการเล่นวิดีโอที่มี UI น้อยที่สุดจะมอบประสบการณ์การใช้งานที่ดีที่สุด

หากแอปของคุณต้องมีการกระทำที่กำหนดเองสำหรับการแสดงภาพซ้อนภาพ โปรดดูหัวข้อ เพิ่มตัวควบคุม ในหน้านี้ นำองค์ประกอบ UI อื่นๆ ออกก่อนที่กิจกรรมจะเข้าสู่โหมด PIP และกู้คืนองค์ประกอบเหล่านั้นเมื่อกิจกรรมกลับไปเป็นแบบเต็มหน้าจออีกครั้ง

เพิ่มตัวควบคุม

หน้าต่าง PIP สามารถแสดงตัวควบคุมได้เมื่อผู้ใช้เปิดเมนูของหน้าต่าง (โดยการแตะหน้าต่างในอุปกรณ์เคลื่อนที่ หรือเลือกเมนูจากรีโมตทีวี)

หากแอปมีเซสชันสื่อที่ใช้งานอยู่ ตัวควบคุมการเล่น หยุดชั่วคราว ถัดไป และก่อนหน้าจะปรากฏขึ้น

นอกจากนี้ คุณยังระบุการกระทำที่กำหนดเองอย่างชัดเจนได้ด้วยการสร้าง PictureInPictureParams ด้วย PictureInPictureParams.Builder.setActions() ก่อนเข้าสู่โหมด PIP และส่งผ่านพารามิเตอร์เมื่อเข้าสู่โหมด PIP โดยใช้ enterPictureInPictureMode(android.app.PictureInPictureParams) หรือ setPictureInPictureParams(android.app.PictureInPictureParams) โปรดระมัดระวัง หากพยายามเพิ่มการกระทำมากกว่า getMaxNumPictureInPictureActions(), คุณจะได้รับการกระทำตามจำนวนสูงสุดเท่านั้น

เล่นวิดีโอต่อขณะอยู่ในโหมด PIP

เมื่อกิจกรรมเปลี่ยนเป็นโหมด PIP ระบบจะวางกิจกรรมไว้ในสถานะหยุดชั่วคราว และเรียกใช้เมธอดของกิจกรรม onPause() การเล่นวิดีโอไม่ควรหยุดชั่วคราวและควรเล่นต่อหากกิจกรรมหยุดชั่วคราวขณะเปลี่ยนไปใช้โหมด PIP

ใน Android 7.0 ขึ้นไป คุณควรหยุดชั่วคราวและเล่นวิดีโอต่อเมื่อระบบเรียกใช้ ของกิจกรรม onStop() และ onStart() การทำเช่นนี้จะช่วยให้คุณไม่ต้องตรวจสอบว่าแอปอยู่ในโหมด PIP ใน onPause() และเล่นต่ออย่างชัดเจน

หากคุณไม่ได้ตั้งค่าแฟล็ก setAutoEnterEnabled เป็น true และต้อง หยุดการเล่นชั่วคราวในการใช้งาน onPause() ให้ตรวจสอบโหมด PIP โดยเรียกใช้ isInPictureInPictureMode() และจัดการการเล่นอย่างเหมาะสม เช่น

Kotlin

override fun onPause() {
    super.onPause()
    // If called while in PiP mode, do not pause playback.
    if (isInPictureInPictureMode) {
        // Continue playback.
    } else {
        // Use existing playback logic for paused activity behavior.
    }
}

Java

@Override
public void onPause() {
    // If called while in PiP mode, do not pause playback.
    if (isInPictureInPictureMode()) {
        // Continue playback.
        ...
    } else {
        // Use existing playback logic for paused activity behavior.
        ...
    }
}

เมื่อกิจกรรมเปลี่ยนจากโหมด PIP กลับไปเป็นโหมดเต็มหน้าจอ ระบบจะ เล่นกิจกรรมต่อและเรียกใช้ onResume() เมธอด

ใช้กิจกรรมการเล่นเพียงรายการเดียวสำหรับการแสดงภาพซ้อนภาพ

ในแอป ผู้ใช้อาจเลือกวิดีโอใหม่ขณะเลือกดูเนื้อหาในหน้าจอหลัก ขณะที่กิจกรรมการเล่นวิดีโออยู่ในโหมด PIP ให้เล่นวิดีโอใหม่ในกิจกรรมการเล่นที่มีอยู่แล้วในโหมดเต็มหน้าจอ แทนที่จะเปิดกิจกรรมใหม่ซึ่งอาจทำให้ผู้ใช้สับสน

หากต้องการให้แน่ใจว่ามีการใช้กิจกรรมเดียวสำหรับคำขอการเล่นวิดีโอและเปลี่ยนเข้าหรือออกจากโหมด PIP ตามความจำเป็น ให้ตั้งค่า android:launchMode ของกิจกรรมเป็น singleTask ในไฟล์ Manifest ดังนี้

<activity android:name="VideoActivity"
    ...
    android:supportsPictureInPicture="true"
    android:launchMode="singleTask"
    ...

ในกิจกรรม ให้ลบล้าง onNewIntent() และจัดการวิดีโอใหม่ โดยหยุดการเล่นวิดีโอที่มีอยู่หากจำเป็น

รองรับ PIP สำหรับแอปกล้องถ่ายรูป

หากต้องการเปิดใช้ PIP สำหรับแอปกล้องถ่ายรูป คุณควรตรวจสอบว่ากล้องยังคงทำงานอยู่ในโหมด PIP โดยไม่ปิดกล้องเมื่อมีการเรียกใช้ onPause() ดังนี้

Java

@Override
public void onPause() {
    super.onPause();
    // Don't close the camera if the app is entering PiP mode
    if (!isInPictureInPictureMode()) {
        closeCamera();
    }
}

เช่นเดียวกับกรณีการใช้งานอื่นๆ ให้ซ่อนองค์ประกอบ UI ที่ไม่จำเป็น (เช่น ตัวควบคุมและการวางซ้อน) และเพิ่มการกระทำที่กำหนดเองเพื่อควบคุมกล้อง (เช่น หยุดการบันทึกหรือพลิกกล้อง)

คำนวณ sourceRectHint สำหรับการเปลี่ยนโหมดที่ราบรื่น

การระบุ sourceRectHint ที่ถูกต้องด้วยพิกัดหน้าจอที่แน่นอนของช่องมองภาพกล้องเป็นสิ่งสำคัญสำหรับภาพเคลื่อนไหวการเข้าสู่โหมดที่ราบรื่น คุณสามารถรับขอบเขตจากมุมมองแสดงตัวอย่างโดยใช้ getGlobalVisibleRect() ดังนี้

Java

View previewView = findViewById(R.id.preview_view);
Rect globalRect = new Rect();
// Ensure the view is laid out before calling getGlobalVisibleRect() to get valid screen coordinates.
previewView.getGlobalVisibleRect(globalRect);
PictureInPictureParams params = new PictureInPictureParams.Builder()
    .setSourceRectHint(globalRect)
    .build();
setPictureInPictureParams(params);

แนวทางปฏิบัติแนะนำ

ระบบอาจปิดใช้ PIP ในอุปกรณ์ที่มี RAM น้อย ก่อนที่แอปจะใช้ PIP, ตรวจสอบว่า PIP พร้อมใช้งานโดยเรียกใช้ hasSystemFeature(PackageManager.FEATURE_PICTURE_IN_PICTURE)

PIP มีไว้สำหรับกิจกรรมที่เล่นวิดีโอแบบเต็มหน้าจอ เมื่อเปลี่ยนกิจกรรมเป็นโหมด PIP ให้หลีกเลี่ยงการแสดงสิ่งอื่นที่ไม่ใช่เนื้อหาวิดีโอ ติดตามเวลาที่ กิจกรรมเข้าสู่โหมด PIP และซ่อนองค์ประกอบ UI ตามที่อธิบายไว้ในการจัดการ UI ระหว่างการแสดงภาพซ้อนภาพ

เมื่อกิจกรรมอยู่ในโหมด PIP กิจกรรมจะไม่ได้รับโฟกัสอินพุตโดยค่าเริ่มต้น หากต้องการรับเหตุการณ์อินพุตขณะอยู่ในโหมด PIP ให้ใช้ MediaSession.setCallback() ดูข้อมูลเพิ่มเติมเกี่ยวกับการใช้ setCallback() ได้ที่หัวข้อแสดงการ์ดกำลังเล่นอยู่

เมื่อแอปอยู่ในโหมด PIP การเล่นวิดีโอในหน้าต่าง PIP อาจทำให้เกิดการรบกวนเสียงกับแอปอื่น เช่น แอปมิวสิกเพลเยอร์หรือแอปการค้นหาด้วยเสียง หากต้องการหลีกเลี่ยงปัญหานี้ ให้ขอโฟกัสเสียงเมื่อเริ่มเล่นวิดีโอ และจัดการการแจ้งเตือนการเปลี่ยนแปลงโฟกัสเสียงตามที่อธิบายไว้ในหัวข้อการจัดการโฟกัสเสียง หากได้รับการแจ้งเตือนการสูญเสียโฟกัสเสียงขณะอยู่ในโหมด PIP ให้หยุดชั่วคราวหรือหยุดการเล่นวิดีโอ

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

โค้ดตัวอย่างเพิ่มเติม

หากต้องการดาวน์โหลดแอปตัวอย่างที่เขียนด้วย Kotlin โปรดดู ตัวอย่างการแสดงภาพซ้อนภาพของ Android (Kotlin)