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

האפליקציה לא אמורה לעבור למצב 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. ב-lambda שמגדיר את ההתנהגות כשהאירוע 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: () -> Unit = {
                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 כדי שהאפליקציה תעבור למצב PiP רק בזמן הנכון:

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 כדי להטמיע אנימציה חלקה

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

  1. מוסיפים את setSourceRectHint() ל-builder רק אם המצב מגדיר שהאפליקציה צריכה לעבור למצב PiP. כך לא צריך לחשב את sourceRect כשהאפליקציה לא צריכה לעבור למצב PiP.
  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)