עסקאות מקטעים

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

אפשר לשמור כל עסקה בסטאק אחורה שמנוהל על ידי FragmentManager, וכך לאפשר למשתמש לנווט אחורה דרך השינויים בקטעים – בדומה לנווט אחורה דרך פעילויות.

אפשר לקבל מופע של FragmentTransaction מה-FragmentManager על ידי קריאה ל-beginTransaction(), כפי שמתואר בדוגמה הבאה:

Kotlin

val fragmentManager = ...
val fragmentTransaction = fragmentManager.beginTransaction()

Java

FragmentManager fragmentManager = ...
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();

הקריאה הסופית בכל FragmentTransaction חייבת להתחייב לעסקה. הקריאה commit() מסמנת ל-FragmentManager שכל הפעולות נוספו לעסקה.

Kotlin

val fragmentManager = ...
// The fragment-ktx module provides a commit block that automatically
// calls beginTransaction and commit for you.
fragmentManager.commit {
    // Add operations here
}

Java

FragmentManager fragmentManager = ...
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();

// Add operations here

fragmentTransaction.commit();

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

בכל FragmentTransaction צריך להשתמש ב-setReorderingAllowed(true):

Kotlin

supportFragmentManager.commit {
    ...
    setReorderingAllowed(true)
}

Java

FragmentManager fragmentManager = ...
fragmentManager.beginTransaction()
    ...
    .setReorderingAllowed(true)
    .commit();

כדי לשמור על תאימות התנהגות, הדגל של ההזמנה מחדש לא מופעל כברירת מחדל. עם זאת, צריך לאפשר ל-FragmentManager לבצע את FragmentTransaction בצורה תקינה, במיוחד כשהיא פועלת ב-back stack ומריצה אנימציות ומעברים. הפעלת הדגל מבטיחה שאם מתבצעות כמה עסקאות יחד, קטעי מעבר (כלומר קטעים שנוספו ולאחר מכן הוחלפו באופן מיידי) לא עוברים שינויים במחזור החיים ולא מתבצעות בהם אנימציות או מעברים. שימו לב שהדגל הזה משפיע גם על הביצוע הראשוני של הטרנזקציה וגם על ביטול העסקה באמצעות popBackStack().

הוספה והסרה של קטעים

כדי להוסיף קטע ל-FragmentManager, צריך להפעיל את add() בעסקה. השיטה הזו מקבלת את המזהה של הקונטיינר של הקטע, וגם את שם הכיתה של הקטע שרוצים להוסיף. המקטע שנוסף מועבר למצב RESUMED. מומלץ מאוד שה-container יהיה FragmentContainerView שחלק מההיררכיה של התצוגה.

כדי להסיר מקטע מהמארח, קוראים לפונקציה remove(), להעביר במכונה של מקטעים שאוחזרה ממנהל המקטעים דרך findFragmentById() או findFragmentByTag(). אם התצוגה המפורטת של הנכס הוספה בעבר למאגר תגים, התצוגה המפורטת תוסר מהמאגר בשלב הזה. הקטע שהוסרה מועבר למצב DESTROYED.

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

קטע הקוד הבא מראה איך להחליף מקטע אחד במקטע אחר:

Kotlin

// Create new fragment
val fragmentManager = // ...

// Create and commit a new transaction
fragmentManager.commit {
    setReorderingAllowed(true)
    // Replace whatever is in the fragment_container view with this fragment
    replace<ExampleFragment>(R.id.fragment_container)
}

Java

// Create new fragment and transaction
FragmentManager fragmentManager = ...
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.setReorderingAllowed(true);

// Replace whatever is in the fragment_container view with this fragment
transaction.replace(R.id.fragment_container, ExampleFragment.class, null);

// Commit the transaction
transaction.commit();

בדוגמה הזו, מופע חדש של ExampleFragment מחליף את החלק, אם יש כזה, שנמצא כרגע במאגר הפריסה שמזוהה באמצעות R.id.fragment_container.

כברירת מחדל, השינויים שבוצעו ב-FragmentTransaction לא מתווספים למחסנית הקודמת. כדי לשמור את השינויים, אפשר להקיש על addToBackStack() ב-FragmentTransaction. מידע נוסף זמין במאמר מנהל קטעי הקוד.

השמירה (commit) היא אסינכרונית

קריאה ל-commit() לא מבצעת את העסקה באופן מיידי. במקום זאת, העסקה מתוזמנת לפעול בשרשור הראשי של ממשק המשתמש ברגע שהיא תהיה מוכנה. עם זאת, אם יש צורך, אפשר להפעיל את עסקת הפלח בשרשור של ממשק המשתמש באופן מיידי באמצעות קריאה ל-commitNow().

חשוב לדעת שהעמודה commitNow לא תואמת לעמודה addToBackStack. לחלופין, אפשר להריץ את כל הקריאות של FragmentTransactions שנשלחו על ידי commit() שעדיין לא בוצעו, באמצעות קריאה ל-executePendingTransactions(). הגישה הזו תואמת ל-addToBackStack.

ברוב המכריע של תרחישי השימוש, commit() הוא כל מה שדרוש.

סדר הפעולות חשוב

הסדר שבו מבצעים פעולות בתוך FragmentTransaction חשוב, במיוחד כשמשתמשים ב-setCustomAnimations(). השיטה הזו מחילה את האנימציות הנתונות על כל פעולות הפירור שמגיעות אחריה.

Kotlin

supportFragmentManager.commit {
    setCustomAnimations(enter1, exit1, popEnter1, popExit1)
    add<ExampleFragment>(R.id.container) // gets the first animations
    setCustomAnimations(enter2, exit2, popEnter2, popExit2)
    add<ExampleFragment>(R.id.container) // gets the second animations
}

Java

getSupportFragmentManager().beginTransaction()
        .setCustomAnimations(enter1, exit1, popEnter1, popExit1)
        .add(R.id.container, ExampleFragment.class, null) // gets the first animations
        .setCustomAnimations(enter2, exit2, popEnter2, popExit2)
        .add(R.id.container, ExampleFragment.class, null) // gets the second animations
        .commit()

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

FragmentTransactions יכול להשפיע על מצב מחזור החיים של קטעים נפרדים שנוספו במסגרת העסקה. כשיוצרים FragmentTransaction, הפונקציה setMaxLifecycle() מגדירה מצב מקסימלי לפלח הנתונים הנתון. לדוגמה, ViewPager2 משתמש ב-setMaxLifecycle() כדי להגביל את המקטעים שלא מופיעים במסך למצב STARTED.

הצגה והסתרה של תצוגות של קטעים

משתמשים ב-methods FragmentTransaction show() ו-hide() כדי להציג ולהסתיר את התצוגה של מקטעים שנוספו לקונטיינר. השיטות האלה מגדירות את החשיפה של הצפיות בנכס בלי להשפיע על מחזור החיים של הנכס.

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

צירוף קטעים ופירוקם

ה-method FragmentTransaction detach() מנתקת את המקטע מממשק המשתמש ומוחקת את היררכיית התצוגות שלו. המקטע נשאר באותו מצב (STOPPED) כמו כשהוא מוצב על המקבץ האחורי. כלומר, הקטע הוסר מממשק המשתמש אבל עדיין מנוהל על ידי מנהל הקטעים.

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

מכיוון ש-FragmentTransaction מטופל כקבוצה אטומית אחת של פעולות, קריאות ל-detach ול-attach באותו מופע של קטע קוד באותה עסקה מבטלות זו את זו בפועל, וכך נמנעים מהרס וליצור מחדש מיידי של ממשק המשתמש של הקטע. אם רוצים לנתק קטע ואז לחבר אותו מחדש באופן מיידי, צריך להשתמש בטרנזקציות נפרדות, מופרדות על ידי executePendingOperations() אם משתמשים ב-commit().