В каком случае использовать Dialog, а в каком DialogFragment
Что проверяют
Понимаете ли вы, что происходит с диалогом при повороте экрана и смерти процесса, и умеете ли безопасно возвращать результат. Следом часто спрашивают, как передать результат из DialogFragment во фрагмент или ViewModel и что меняется в Compose.
Как отвечать
Разница в том, кто управляет жизненным циклом:
DialogиAlertDialog: обычное окно, привязанное кContextактивности. При смене конфигурации активность пересоздаётся, а диалог сам не восстанавливается: он пропадает вместе с введёнными данными, а если его не закрыли, в логе появляетсяWindowLeaked;DialogFragment: фрагмент, внутри которого живётDialog. Им управляетFragmentManager, поэтому после поворота или восстановления процесса он пересоздаётся сам, а состояние сохраняется черезonSaveInstanceStateиarguments.
Правило для View-системы: диалог, который должен пережить поворот, показывайте через DialogFragment, а сам Dialog создавайте в onCreateDialog, например через MaterialAlertDialogBuilder(requireContext()).
Правила работы с DialogFragment:
- аргументы через
Bundle: фрагмент пересоздаётся конструктором без параметров, поэтому лямбды и объекты, переданные в конструктор или сеттер, после поворота исчезнут; - результат через Fragment Result API:
setFragmentResultв диалоге иsetFragmentResultListenerу получателя.setTargetFragmentустарел; - показ:
show(parentFragmentManager, TAG)послеonSaveInstanceStateпадает сIllegalStateException, поэтому показ по событию надо привязывать к жизненному циклу; - навигация: в Navigation Component диалог объявляется назначением
<dialog>.
В Compose фрагмент не нужен: AlertDialog показывается по флагу, а флаг живёт в rememberSaveable или во ViewModel и переживает поворот.
Где спотыкаются
Передают колбэк в конструктор DialogFragment. После поворота колбэка уже нет, и кнопка ничего не делает или роняет приложение.
Не закрывают Dialog при уничтожении активности. Отсюда WindowLeaked и утечка.
Считают, что DialogFragment устарел из-за Compose. В проектах на View он остаётся основным способом.