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