הצגת תיבות דו-שיח עם DialogFragment

DialogFragment הוא תת-מחלקה מיוחדת של מקטעים שנועדה ליצירה ולאירוח תיבות דו-שיח. למרות שלא צריך ומארח את תיבת הדו-שיח בתוך מקטע, כך FragmentManager מנהלים את המדינה (State) של תיבת הדו-שיח, ולשחזר את תיבת הדו-שיח באופן אוטומטי מתרחשת שינוי.

יצירת DialogFragment

כדי ליצור DialogFragment, צריך ליצור כיתה שמרחיבה DialogFragment וגם לשנות onCreateDialog(), כפי שאפשר לראות בדוגמה הבאה.

Kotlin

class PurchaseConfirmationDialogFragment : DialogFragment() {
    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog =
            AlertDialog.Builder(requireContext())
                .setMessage(getString(R.string.order_confirmation))
                .setPositiveButton(getString(R.string.ok)) { _,_ -> }
                .create()

    companion object {
        const val TAG = "PurchaseConfirmationDialog"
    }
}

Java

public class PurchaseConfirmationDialogFragment extends DialogFragment {
   @NonNull
   @Override
   public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
       return new AlertDialog.Builder(requireContext())
               .setMessage(getString(R.string.order_confirmation))
               .setPositiveButton(getString(R.string.ok), (dialog, which) -> {} )
               .create();
   }

   public static String TAG = "PurchaseConfirmationDialog";
}

דומה לאופן שבו onCreateView() יוצרת שורש View במקטע רגיל, onCreateDialog() יוצר Dialog להצגה כחלק מ-DialogFragment. הכינויים של DialogFragment מוצגים Dialog במצבים המתאימים במחזור החיים של המקטע.

כמו ב-onCreateView(), אפשר להחזיר כל מחלקה של Dialog החל מ-onCreateDialog() ואינם מוגבלים לשימוש AlertDialog

הצגת DialogFragment

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

במהלך היצירה DialogFragment מתוך Fragment, השתמשו ב- הצאצא FragmentManager כדי שהמצב ישוחזר באופן תקין אחרי השינויים בהגדרות האישיות. תג שאינו null מאפשר להשתמש findFragmentByTag() כדי לאחזר את DialogFragment במועד מאוחר יותר.

Kotlin

// From another Fragment or Activity where you wish to show this
// PurchaseConfirmationDialogFragment.
PurchaseConfirmationDialogFragment().show(
     childFragmentManager, PurchaseConfirmationDialog.TAG)

Java

// From another Fragment or Activity where you wish to show this
// PurchaseConfirmationDialogFragment.
new PurchaseConfirmationDialogFragment().show(
       getChildFragmentManager(), PurchaseConfirmationDialog.TAG);

לשליטה רבה יותר על FragmentTransaction אפשר להשתמש show() עומס יתר שמקבל FragmentTransaction קיים.

מחזור החיים של DialogFragment

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

  • onCreateDialog(): לבטל את הקריאה החוזרת (callback) הזו כדי לספק Dialog למקטע לנהל ולהציג.
  • onDismiss(): לבטל את הקריאה החוזרת (callback) הזו אם אתם צריכים לבצע לוגיקה מותאמת אישית כלשהי Dialog נסגר, למשל שחרור משאבים או ביטול הרשמה ממקורות גלויים.
  • onCancel(): לבטל את הקריאה החוזרת (callback) הזו אם אתם צריכים לבצע לוגיקה מותאמת אישית כאשר Dialog בוטל.

DialogFragment מכיל גם שיטות לסגירה או להגדרה של אפשרות ביטול של DialogFragment:

  • dismiss(): סוגרים את המקטע ואת תיבת הדו-שיח שלו. אם המקטע התווסף אל חזרה לערימה, כל מצב ה-BackStack, עד הרשומה הזו, כולל הרשומה, יקפוץ. אחרת, עסקה חדשה מחויבת להסרת המקטע.
  • setCancelable(): המדיניות הזו קובעת אם ניתן לבטל את Dialog שמוצג. שימוש בשיטה הזו במקום להתקשר ישירות Dialog.setCancelable(boolean)

לא לשנות onCreateView() או onViewCreated() כשמשתמשים ב-DialogFragment עם Dialog. תיבות דו-שיח הן לא רק צפיות - יש להם חלון משלהם. לכן, לא מספיק לשנות onCreateView() בנוסף, אף פעם לא מתבצעת קריאה אל onViewCreated() DialogFragment בהתאמה אישית, אלא אם ביטלת את onCreateView() ו מספקת תצוגה שאינה אפסית.

שימוש בתצוגות בהתאמה אישית

אפשר ליצור DialogFragment ולהציג תיבת דו-שיח על ידי ביטול onCreateView(). אפשר לתת לו layoutId, כמו בקטע רגיל, או להשתמש DialogFragment constructor.

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

מחלקות משנה מסוימות של DialogFragment, כמו BottomSheetDialogFragment, להטמיע את התצוגה בתיבת דו-שיח שמעוצבת כגיליון תחתון.