בתג הפעילות של הקובץ AndroidManifest.xml, מבצעים את הפעולות הבאות:
- מוסיפים את
supportsPictureInPictureומגדירים אותו כ-trueכדי להצהיר שאתם משתמשים בתמונה בתוך תמונה (PiP) באפליקציה. - מוסיפים את
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">
בקוד של Compose, מבצעים את הפעולות הבאות:
- צריך להוסיף את התוסף הזה באתר
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") }
הוספת "תמונה בתוך תמונה" ביציאה מהאפליקציה בגרסאות קודמות ל-Android 12
כדי להוסיף "תמונה בתוך תמונה" בגרסאות קודמות ל-Android 12, משתמשים ב-addOnUserLeaveHintProvider. כדי להוסיף תמונה בתוך תמונה בגרסאות Android שקדמו ל-Android 12:
- הוסיפו שער גרסה כדי שהקוד הזה יהיה נגיש רק בגרסאות O עד R.
- משתמשים ב-
DisposableEffectעםContextכמפתח. - בתוך
DisposableEffect, מגדירים את ההתנהגות שלonUserLeaveHintProviderכשהוא מופעל באמצעות lambda. ב-lambda, מפעילים אתenterPictureInPictureMode()ב-findActivity()ומעבירים אתPictureInPictureParams.Builder().build(). - מוסיפים את
addOnUserLeaveHintListenerבאמצעותfindActivity()ומעבירים את הלמבדה. - ב-
onDispose, מוסיפים אתremoveOnUserLeaveHintListenerבאמצעותfindActivity()ומעבירים את הלמבדה.
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 { 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") }
הוספת "תמונה בתוך תמונה" ביציאה מהאפליקציה בגרסאות Android 12 ואילך
בגרסאות Android אחרי Android 12, ה-PictureInPictureParams.Builder מתווסף באמצעות משתנה שמועבר לנגן הווידאו של האפליקציה.
- יוצרים
modifierומפעילים בו אתonGloballyPositioned. הקואורדינטות של הפריסה ישמשו בשלב מאוחר יותר. - יוצרים משתנה ל-
PictureInPictureParams.Builder(). - מוסיפים הצהרת
ifכדי לבדוק אם ה-SDK הוא S ואילך. אם כן, מוסיפים אתsetAutoEnterEnabledל-builder ומגדירים אותו ל-trueכדי להיכנס למצב PiP בהחלקה. כך האנימציה חלקה יותר מאשר כשעוברים דרךenterPictureInPictureMode. - משתמשים ב-
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, ודאו שהנגן לא ריק ושגודל הסרטון בנגן לא שווה ל-VideoSize.UNKNOWN לפני שאתם מגדירים את יחס הגובה-רוחב.
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)
אם אתם משתמשים בנגן מותאם אישית, הגדירו את יחס הגובה-רוחב של הנגן באמצעות התחביר הספציפי לנגן שלכם. חשוב לזכור שאם גודל הנגן משתנה במהלך ההפעלה, והוא חורג מהגבולות התקינים של יחס הגובה-רוחב, האפליקציה תקרוס. יכול להיות שתצטרכו להוסיף בדיקות לגבי מתי אפשר לחשב את יחס הגובה-רוחב, בדומה לאופן שבו זה נעשה בנגן media3.