להיכנס למצב PiP בזמנים הנכונים

אסור שהאפליקציה תיכנס למצב תמונה בתוך תמונה במצבים הבאים:

  • אם הסרטון מושהה או נעצר.
  • אם אתם נמצאים בדף אחר באפליקציה ולא בנגן הווידאו.

כדי לקבוע מתי האפליקציה תיכנס למצב PiP, מוסיפים משתנה שעוקב אחרי המצב של נגן הווידאו באמצעות mutableStateOf.

החלפת מצב בהתאם להפעלה של סרטון

כדי להחליף את המצב בהתאם להפעלה של נגן הווידאו, מוסיפים מאזין בנגן הווידאו. החלפת המצב של משתנה המצב על סמך ההגדרה אם הסרטון מוצג או לא:

player.addListener(object : Player.Listener {
    override fun onIsPlayingChanged(isPlaying: Boolean) {
        shouldEnterPipMode = isPlaying
    }
})

שינוי המצב בהתאם לשחרור הנגן

כשמשחררים את הנגן, מגדירים את משתנה המצב ל-false:

fun releasePlayer() {
    shouldEnterPipMode = false
}

שימוש במצב כדי להגדיר אם נכנסים למצב PiP (גרסאות Android קודמות ל-12)

  1. הוספת PiP בגרסאות קודמות ל-12 מתבצעת באמצעות DisposableEffect, ולכן צריך ליצור משתנה חדש באמצעות rememberUpdatedState עם newValue שמוגדר כמשתנה המצב. כך תוכלו לוודא שהגרסה המעודכנת נמצאת בשימוש ב-DisposableEffect.
  2. בפונקציית הלמדה שמגדירה את ההתנהגות כשמופעלת OnUserLeaveHintListener מוסיפים הצהרת if עם משתנה המצב סביב הקריאה אל enterPictureInPictureMode():

    val currentShouldEnterPipMode by rememberUpdatedState(newValue = shouldEnterPipMode)
    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 = Runnable {
                if (currentShouldEnterPipMode) {
                    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)

מעבירים את משתנה המצב אל setAutoEnterEnabled כדי שהאפליקציה תיכנס למצב תמונה בתוך תמונה רק בזמן הנכון:

val pipModifier = modifier.onGloballyPositioned { layoutCoordinates ->
    val builder = PictureInPictureParams.Builder()

    // Add autoEnterEnabled for versions S and up
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
        builder.setAutoEnterEnabled(shouldEnterPipMode)
    }
    context.findActivity().setPictureInPictureParams(builder.build())
}

VideoPlayer(pipModifier)

שימוש ב-setSourceRectHint לאנימציה חלקה

setSourceRectHint API יוצר אנימציה חלקה יותר למעבר למצב תמונה בתוך תמונה (PiP). ב-Android 12 ואילך, הוא גם יוצר אנימציה חלקה יותר ליציאה ממצב תמונה בתוך תמונה. מוסיפים את ה-API הזה לכלי ליצירת חלון צף כדי לציין את האזור של הפעילות שיהיה גלוי אחרי המעבר לחלון צף.

  1. מוסיפים רק setSourceRectHint() ל-builder אם המדינה מגדירה שהאפליקציה צריכה להיכנס למצב תמונה בתוך תמונה. כך נמנעת ההפעלה של sourceRect כשהאפליקציה לא צריכה להיכנס למצב תמונה בתוך תמונה.
  2. כדי להגדיר את הערך sourceRect, משתמשים ב-layoutCoordinates שמופיע בפונקציה onGloballyPositioned של המשנה.
  3. מתקשרים אל setSourceRectHint() ב-builder ומעבירים את המשתנה sourceRect.

val context = LocalContext.current

val pipModifier = modifier.onGloballyPositioned { layoutCoordinates ->
    val builder = PictureInPictureParams.Builder()
    if (shouldEnterPipMode) {
        val sourceRect = layoutCoordinates.boundsInWindow().toAndroidRectF().toRect()
        builder.setSourceRectHint(sourceRect)
    }

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
        builder.setAutoEnterEnabled(shouldEnterPipMode)
    }
    context.findActivity().setPictureInPictureParams(builder.build())
}

VideoPlayer(pipModifier)