เพิ่มวิดีโอโดยใช้การแสดงภาพซ้อนภาพ (PIP)

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

ตั้งแต่ 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 เป็นต้นไป ผู้ใช้ยังทำสิ่งต่อไปนี้ได้ด้วย

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

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

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

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

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

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

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

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

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

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

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

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

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

ตั้งแต่ Android 12 เป็นต้นไป คุณสามารถเปลี่ยนกิจกรรมเป็นโหมด PIP ได้โดยการตั้งค่า Flag 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
  • การปิดใช้การปรับขนาดอย่างราบรื่นสำหรับเนื้อหาที่ไม่ใช่วิดีโอ

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

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

ตั้งแต่ Android 12 เป็นต้นไป Flag 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 เราขอแนะนำให้แนบโปรแกรมรับฟังการเปลี่ยนแปลงเลย์เอาต์กับวิดีโอเพลเยอร์ด้วย โดยทำดังนี้

    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 เพิ่ม Flag setSeamlessResizeEnabled ซึ่งช่วยให้ภาพเคลื่อนไหวที่ค่อยๆ เปลี่ยนรูปภาพราบรื่นขึ้นมากเมื่อปรับขนาดเนื้อหาที่ไม่ใช่วิดีโอในหน้าต่าง PiP ก่อนหน้านี้การปรับขนาดเนื้อหาที่ไม่ใช่วิดีโอในหน้าต่าง PIP อาจทำให้เกิดข้อบกพร่องที่มองเห็นได้ชัดเจน

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

Kotlin

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

Java

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

จัดการ UI ระหว่างใช้โหมด PIP

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

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

นักพัฒนาแอปใช้การเรียกกลับ onPictureInPictureModeChanged() เพื่อกำหนดตรรกะที่จะสลับการแสดงผลขององค์ประกอบ UI ที่วางซ้อน Callback นี้จะทริกเกอร์เมื่อภาพเคลื่อนไหวของ 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 น้อยที่สุดจะให้ประสบการณ์การใช้งานที่ดีที่สุดแก่ผู้ใช้

หากแอปของคุณต้องระบุการดำเนินการที่กำหนดเองสำหรับ PiP โปรดดูเพิ่มการควบคุมในหน้านี้ นำองค์ประกอบ 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() หรือไม่ และไม่ต้องเล่นต่ออย่างชัดแจ้ง

หากคุณยังไม่ได้ตั้งค่า Flag 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

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

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

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

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

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

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

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

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

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

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

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

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