Как правильно отклонить DialogFragment?
Документы говорят это для метода dismiss()
из класса Dialog
:
Закрыть этот диалог, убрав его с экрана. Этот метод может быть безопасно вызван из любого потока. Обратите внимание, что вам не следует переопределять этот метод для очистки после onStop()
диалогового окна, вместо этого реализуйте это в onStop()
.
В моем коде все, что я делаю, это вызываю getDialog().dismiss()
чтобы закрыть его. Но я больше ничего не делаю и даже не использую onStop()
. Поэтому я спрашиваю, как именно закрыть DialogFragment
чтобы избежать утечек памяти и т.д.
Ответы
Ответ 1
tl; dr: Правильный способ закрыть DialogFragment
- использовать dismiss()
непосредственно в диалоговом окне DialogFragment.
Подробнее. документация состояния DialogFragment
Контроль диалога (выбор, когда показывать, скрывать, отклонять его) должен выполняться через API здесь, а не с прямыми вызовами в диалоговом окне.
Таким образом, вы не должны использовать getDialog().dismiss()
, так как это вызовет dismiss()
в диалоговом окне. Вместо этого вы должны использовать метод dismiss()
самого DialogFragment:
public void reject()
Отключите фрагмент и его диалог. Если фрагмент был добавлен в задний стек, будет выведено все состояние предыдущего стека до и включая эту запись. В противном случае будет предпринята новая транзакция для удаления фрагмента.
Как вы можете видеть, это не только закрывает диалог, но и обрабатывает транзакции фрагментов, участвующие в этом процессе.
Вам нужно использовать onStop
, если вы явно создали какие-либо ресурсы, требующие ручной очистки (закрытие файлов, закрытие курсоров и т.д.). Даже тогда я бы переопределил onStop
диалогового окна DialogFragment, а не onStop
базового диалога.
Ответ 2
Я думаю, что лучший способ закрыть DialogFragment
это:
Fragment prev = getSupportFragmentManager().findFragmentByTag("fragment_dialog");
if (prev != null) {
DialogFragment df = (DialogFragment) prev;
df.dismiss();
}
Таким образом, вам не нужно держать ссылку на DialogFragment
и вы можете закрыть его из DialogFragment
.
Ответ 3
Вы должны отклонить вас Dialog
в onPause()
, чтобы переопределить его.
Также перед увольнением вы можете проверить null
и показывать как ниже фрагмент:
@Override
protected void onPause() {
super.onPause();
if (dialog != null && dialog.isShowing()) {
dialog.dismiss();
}
}
Ответ 4
Я отдал ответ Терелу. Я просто хотел опубликовать это для любых пользователей Kotlin:
supportFragmentManager.findFragmentByTag(TAG_DIALOG)?.let {
(it as DialogFragment).dismiss()
}
Ответ 5
Котлинская версия ответа Тереля
(fragmentManager.findFragmentByTag(TAG) as? DialogFragment)?.dismiss()
Ответ 6
Почему бы вам не попробовать использовать только этот код:
dismiss();
Если вы хотите удалить фрагмент диалога самостоятельно. Вы можете просто поместить этот код внутри фрагмента диалога, где вы хотите закрыть диалог.
Например:
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dismiss();
}
});
Это закроет последний фрагмент диалога, который отображается на экране.
Надеюсь, это поможет вам.
Ответ 7
Просто вызовите dismiss() из фрагмента, который вы хотите удалить.
imageView3.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
dismiss();
}
});
Ответ 8
В других ответах есть ссылки на официальные документы (DialogFragment Reference), но нет упоминания о приведенном там примере:
void showDialog() {
mStackLevel++;
// DialogFragment.show() will take care of adding the fragment
// in a transaction. We also want to remove any currently showing
// dialog, so make our own transaction and take care of that here.
FragmentTransaction ft = getFragmentManager().beginTransaction();
Fragment prev = getFragmentManager().findFragmentByTag("dialog");
if (prev != null) {
ft.remove(prev);
}
ft.addToBackStack(null);
// Create and show the dialog.
DialogFragment newFragment = MyDialogFragment.newInstance(mStackLevel);
newFragment.show(ft, "dialog");
}
Это удаляет любой отображаемый в данный момент диалог, создает новый DialogFragment с аргументом и показывает его как новое состояние в заднем стеке. Когда транзакция извлечена, текущий DialogFragment и его Dialog будут уничтожены, а предыдущий (если есть) повторно показан. Обратите внимание, что в этом случае DialogFragment позаботится о выталкивании, транзакция Dialog отклоняется отдельно от него.
Для своих нужд я изменил его на:
FragmentManager manager = getSupportFragmentManager();
Fragment prev = manager.findFragmentByTag(TAG);
if (prev != null) {
manager.beginTransaction().remove(prev).commit();
}
MyDialogFragment fragment = new MyDialogFragment();
fragment.show(manager, TAG);
Ответ 9
чуть ниже код в порядке!
dismiss();