הוספת תמיכה בתנועת החזרה החזויה

איור 1. הדמיה של מראה ותחושה של חיזוי תנועת החזרה בטלפון

התכונה 'חיזוי החזרה', תכונת ניווט באמצעות תנועות, מאפשרת למשתמשים לראות תצוגה מקדימה של המקום שאליו הם יגיעו אם יחליקו כדי לחזור.

לדוגמה, שימוש בתנועת חזרה יכול להציג תצוגה מקדימה עם אנימציה של מסך הבית מאחורי האפליקציה, כמו שמוצג ב-mockup באיור 1.

החל מ-Android 15, האפשרות למפתחים להפעלת אנימציות של חיזוי החזרה לא זמינה יותר. אנימציות מערכת כמו חזרה למסך הבית, מעבר בין משימות ומעבר בין פעילויות מוצגות עכשיו באפליקציות שהופעלה בהן התכונה 'חיזוי של תנועת החזרה' באופן מלא או ברמת הפעילות.

אפשר לבדוק את האנימציה הזו של חזרה למסך הבית (כפי שמתואר בקטע הבא בדף הזה).

כדי לתמוך בחיזוי תנועת החזרה, צריך לעדכן את האפליקציה באמצעות OnBackPressedCallback התואם לדור קודם ב-AndroidX Activity 1.6.0 או ב-API בגרסה מתקדמת יותר, או באמצעות ה-API החדש של הפלטפורמה OnBackInvokedCallback. רוב האפליקציות משתמשות ב-AndroidX API שתואם לדורות קודמים.

העדכון הזה מספק נתיב העברה ליירוט נכון של ניווט אחורה. במסגרת ההעברה, צריך להחליף את היירוטים של ניווט אחורה מ-KeyEvent.KEYCODE_BACK ומכל המחלקות עם שיטות onBackPressed כמו Activity ו-Dialog בממשקי ה-API החדשים של המערכת לניווט אחורה.

סרטון Codelab ו-Google I/O

בנוסף לשימוש במסמכי העזרה שבדף הזה, כדאי לנסות את ה-Codelab שלנו. הוא מספק הטמעה של תרחיש שימוש נפוץ של WebView שמטפל בחיזוי תנועת החזרה באמצעות AndroidX Activity APIs.

אפשר גם לצפות בסרטון מ-Google I/O, שכולל דוגמאות נוספות להטמעה של AndroidX וממשקי API של הפלטפורמה.

טיפול בתנועות חזרה בהתאמה אישית בכתיבה

הספרייה Compose מספקת את הרכיב PredictiveBackHandler שאפשר להשתמש בו כדי לטפל במחוות חזרה מותאמות אישית. ממשק ה-API הזה מאפשר להגיב לתנועת החלקה אחורה ומספק Flow של אובייקטים מסוג BackEventCompat שאפשר להשתמש בהם כדי להטמיע אנימציות או מעברים מותאמים אישית בזמן שהמשתמש מחליק.

כדי להשתמש ב-PredictiveBackHandler, צריך לוודא שהאפליקציה כוללת את התלות androidx.activity:activity-compose (גרסה 1.8.0 ואילך):

// In your build.gradle.kts file:
dependencies {
    implementation("androidx.activity:activity-compose:1.8.0")
}

PredictiveBackHandler(enabled = isBackHandlerEnabled) { progress: Flow<BackEventCompat> ->
    try {
        progress.collect { backEvent ->
            // Update your UI or animation based on backEvent.progress.
        }
        // Handle the final back action (e.g., navigate back).
    } catch (e: CancellationException) {
        // Back gesture was cancelled, reset your UI.
    }
}

אם אתם צריכים רק ליירט את תנועת החזרה בלי לעקוב אחרי ההתקדמות, אתם יכולים להשתמש ב-BackHandler.

עדכון אפליקציה שמשתמשת בניווט חזרה שמוגדר כברירת מחדל

התכונה 'חיזוי החזרה' מופעלת כברירת מחדל.

אם האפליקציה שלכם משתמשת ב-Fragments או ב-Navigation Component, צריך גם לשדרג ל-AndroidX Activity 1.6.0 או לגרסה מתקדמת יותר.

עדכון אפליקציה שמשתמשת בניווט לאחור מותאם אישית

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

איך האפליקציה מטפלת בניווט אחורה נתיב ההעברה המומלץ (הקישור נמצא בדף הזה)
‫AndroidX APIs העברה של הטמעה קיימת של AndroidX back
ממשקי API של פלטפורמות שלא נתמכות העברה של אפליקציית AndroidX שמכילה ממשקי API של ניווט אחורה שלא נתמכים אל ממשקי AndroidX API

העברה של הטמעה של ניווט אחורה ב-AndroidX

זהו התרחיש הנפוץ ביותר (והמומלץ ביותר). הוא חל על אפליקציות חדשות או קיימות שמטמיעות טיפול מותאם אישית בניווט באמצעות תנועות עם OnBackPressedDispatcher, כפי שמתואר במאמר הוספת ניווט מותאם אישית אחורה.

כדי לוודא שממשקי API שכבר משתמשים ב-OnBackPressedDispatcher (כמו Fragments ו-Navigation Component) פועלים בצורה חלקה עם חיזוי תנועת החזרה, צריך לשדרג ל-AndroidX Activity 1.6.0 או לגרסה מתקדמת יותר.

// In your build.gradle file:
dependencies {
    // Add this in addition to your other dependencies
    implementation "androidx.activity:activity:1.6.0"
}

העברה של אפליקציית AndroidX שמכילה ממשקי API של ניווט אחורה שלא נתמכים אל AndroidX APIs

אם האפליקציה שלכם משתמשת בספריות AndroidX אבל מטמיעה או מפנה אל ממשקי ה-API הלא נתמכים של הניווט אחורה, תצטרכו לעבור לשימוש בממשקי AndroidX API כדי לתמוך בהתנהגות החדשה.

כדי להעביר ממשקי API לא נתמכים אל AndroidX APIs:

  1. מעבירים את הלוגיקה של הטיפול בפעולת החזרה במערכת אל OnBackPressedDispatcher של AndroidX עם הטמעה של OnBackPressedCallback. הנחיות מפורטות זמינות במאמר בנושא הוספת ניווט מותאם אישית אחורה.

  2. משביתים את OnBackPressedCallback כשמוכנים להפסיק את היירוט של תנועת החזרה.

  3. כדי להפסיק את היירוט של אירועי חזרה, משתמשים ב-OnBackPressed או ב-KeyEvent.KEYCODE_BACK.

  4. חשוב לשדרג ל-AndroidX Activity 1.6.0 או לגרסה מתקדמת יותר.

    // In your build.gradle file:
    dependencies {
        // Add this in addition to your other dependencies
        implementation "androidx.activity:activity:1.6.0"
    }
    

ביטול ההסכמה לשימוש בתכונה 'חיזוי החזרה'

כדי לבטל את ההסכמה, בתג <application> ב-AndroidManifest.xml, מגדירים את הדגל android:enableOnBackInvokedCallback לערך false.

<application
    ...
    android:enableOnBackInvokedCallback="false"
    ... >
...
</application>

אם מגדירים את המדיניות כ-False, מתבצעות הפעולות הבאות:

  • השבתה של אנימציית המערכת של חיזוי תנועת החזרה.
  • המערכת מתעלמת מ-OnBackInvokedCallback, אבל שיחות OnBackPressedCallback ממשיכות לפעול.

סירוב ברמת הפעילות

הדגל android:enableOnBackInvokedCallback מאפשר להשבית את האנימציות החזויות של המערכת ברמת הפעילות. ההתנהגות הזו מקלה על העברת אפליקציות גדולות עם כמה פעילויות לתנועות חיזוי לחזרה.

הקוד הבא מציג דוגמה להגדרה של enableOnBackInvokedCallback כדי להפעיל את אנימציית החזרה למסך הבית מה-MainActivity:

<manifest ...>
    <application . . .

        android:enableOnBackInvokedCallback="false">

        <activity
            android:name=".MainActivity"
            android:enableOnBackInvokedCallback="true"
            ...
        </activity>
        <activity
            android:name=".SecondActivity"
            android:enableOnBackInvokedCallback="false"
            ...
        </activity>
    </application>
</manifest>

כשמשתמשים בדגל android:enableOnBackInvokedCallback, חשוב לזכור את הנקודות הבאות:

  • ההגדרה android:enableOnBackInvokedCallback=false משביתה את האנימציות החזויות של החזרה אחורה ברמת הפעילות או ברמת האפליקציה, בהתאם למיקום שבו מגדירים את התג, ומורה למערכת להתעלם מקריאות ל-OnBackInvokedCallback platform API. עם זאת, קריאות ל-OnBackPressedCallback ממשיכות לפעול כי OnBackPressedCallback תואם לגרסאות קודמות וקורא ל-API‏ onBackPressed, שלא נתמך בגרסאות קודמות ל-Android 13.
  • הגדרת הדגל enableOnBackInvokedCallback ברמת האפליקציה קובעת את ערך ברירת המחדל לכל הפעילויות באפליקציה. אפשר לשנות את ברירת המחדל לכל פעילות בנפרד על ידי הגדרת הדגל ברמת הפעילות, כמו שמוצג בדוגמת הקוד הקודמת.

הנחיות לשימוש בתכונה 'התקשרות חו

כשמשתמשים בקריאות החוזרות (callback) הנתמכות של המערכת להחזרה: PredictiveBackHandler או BackHandler (ב-Compose), OnBackPressedCallback או OnBackInvokedCallback.

קביעת מצב ממשק המשתמש שמאפשר להפעיל ולהשבית כל קריאה חוזרת (callback)

מצב ממשק המשתמש הוא מאפיין שמתאר את ממשק המשתמש. מומלץ לפעול לפי השלבים הכלליים הבאים.

  1. קובעים את מצב ממשק המשתמש שמאפשר להפעיל ולהשבית כל קריאה חוזרת.

  2. מגדירים את ערך דינמי באמצעות סוג של מאגר נתונים גלויים, כמו StateFlow או Compose State, ומפעילים או משביתים את קריאה חוזרת כשהערך הדינמי משתנה.

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

שימוש בהתקשרות חזרה של המערכת ללוגיקה של ממשק המשתמש

הלוגיקה של ממשק המשתמש קובעת איך להציג את ממשק המשתמש. אפשר להשתמש בקריאות חוזרות (callback) של המערכת כדי להריץ לוגיקה של ממשק משתמש, כמו הצגת תיבת דו-שיח או הפעלת אנימציה.

אם האפליקציה מאפשרת OnBackPressedCallback או OnBackInvokedCallback עם PRIORITY_DEFAULT או PRIORITY_OVERLAY, האנימציות של התנועה החזויה אחורה לא פועלות, ואתם צריכים לטפל באירוע של התנועה אחורה. אל תיצרו את פונקציות ה-callback האלה כדי להריץ לוגיקה עסקית או כדי לבצע רישום ביומן.

אם האפליקציה צריכה להריץ לוגיקה עסקית או לרשום ביומן כשהמשתמש מחליק כדי לחזור, אפשר להשתמש בגישות הבאות:

  • ב-Compose: מתבצעת כניסה ל-callback‏ onCleared() של ViewModel שמשויך ליעד של Compose. זהו האות הכי טוב לדעת מתי יעד של Compose מוצא ממקבץ הפעילויות הקודמות (back stack) ונהרס.
  • ב-Android מגרסה 16 ואילך: משתמשים ב-OnBackInvokedCallback עם PRIORITY_SYSTEM_NAVIGATION_OBSERVER. הפעולה הזו יוצרת קריאה חוזרת (callback) של observer שלא צורכת את אירוע החזרה. לדוגמה, אפשר לרשום את פונקציית הקריאה החוזרת הזו כשהמשתמש מחליק אחורה מהפעילות הבסיסית (יוצא מהאפליקציה) כדי לרשום את אירוע החזרה או להפעיל לוגיקה עסקית, ועדיין לאפשר את הפעלת האנימציה של החזרה למסך הבית.
  • באפליקציות מבוססות-תצוגה: רישום ביומן בתוך קריאות חוזרות (callback) של מחזור החיים או של ערימת החזרה (back stack) במקום שימוש באירועי חזרה:
    • במעברים בין פעילויות, בודקים אם isFinishing הוא true בתוך Activity.onDestroy().
    • במעברים בין קטעים, צריך לבדוק אם isRemoving הוא true בתוך מחזור החיים של התצוגה של Fragment‏ onDestroy(), או להשתמש ב-FragmentManager.OnBackStackChangedListener (onBackStackChangeStarted /‏ onBackStackChangeCommitted).

יצירת קריאות חוזרות עם אחריות יחידה

אפשר להוסיף כמה פונקציות callback ל-dispatcher. הקריאות החוזרות מתווספות למחסנית שבה הקריאה החוזרת האחרונה שהופעלה מטפלת במחוות הבאות של חזרה, עם קריאה חוזרת אחת לכל מחווה של חזרה.

קל יותר לנהל את מצב ההפעלה של קריאה חוזרת אם לקריאה החוזרת הזו יש אחריות אחת. לדוגמה:

סדר הקריאות החוזרות במחסנית ב-Compose.
איור 2. דיאגרמה של סטאק השיחות החוזרות ב-Compose.

באיור 2 אפשר לראות איך יכולות להיות כמה פונקציות קריאה חוזרת במקבץ, וכל אחת אחראית לדבר אחד. ב-Compose, הקריאות החוזרות מוערכות מהרכיב הניתן להרכבה הפנימי ביותר אל הרכיב החיצוני ביותר, וקריאה חוזרת מופעלת רק אם הקריאות החוזרות שקדמו לה במחסנית מושבתות:

  • ההודעה 'בטוח שאתה רוצה...' האפשרות PredictiveBackHandler מופעלת כשהמשתמש מזין נתונים בטופס, ומושבתת בכל מצב אחר. כשההגדרה הזו מופעלת, היא מיירטת את תנועת החזרה כדי להציג תיבת דו-שיח לאישור או אנימציה מותאמת אישית באפליקציה.
  • הפונקציה BackHandler ברמת המסך מופעלת אם הפונקציה הקודמת לטיפול בקריאה חוזרת מושבתת. בדוגמה הזו, היא מושבתת.
  • פונקציית הקריאה החוזרת NavHost מטפלת בניווט לאחור כדי להציג יעדים ממקבץ הפעילויות הקודמות (back stack) אם השבתתם פונקציות קריאה חוזרת מותאמות אישית קודמות.
  • לבסוף, המערכת מטפלת בתנועת החזרה אם כל הקריאות החוזרות הקודמות מושבתות. כשמקבץ הפעילויות הקודמות (back stack) נמצא ביעד הבסיסי שלו, המערכת מפעילה אנימציות ברמת המערכת, כמו חזרה למסך הבית, מעבר בין פעילויות ומעבר בין משימות.

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

בדיקת האנימציה של חיזוי תנועת החזרה

החל מ-Android 15, אנימציות מערכת כמו חזרה למסך הבית, מעבר בין משימות ומעבר בין פעילויות מופעלות כברירת מחדל באפליקציות שתומכות בניווט עם חיזוי החזרה. הם כבר לא מוסתרים באפשרות למפתחים.

במכשירים עם Android 13 או Android 14, אפשר להפעיל את אפשרות המפתח כדי לבדוק את האנימציה של החזרה למסך הבית שמוצגת באיור 1:

  1. במכשיר, עוברים אל הגדרות > מערכת > אפשרויות למפתחים.

  2. בוחרים באפשרות חיזוי החזרה אנימציות.

  3. מפעילים את האפליקציה המעודכנת ומשתמשים בתנועת החזרה כדי לראות את הפעולה.