Ответ 1
DialogFragment
имеет метод под названием dismissAllowingStateLoss()
Я начал использовать DialogFragment, потому что они хорошо работают с изменениями ориентации и т.д. Но есть неприятная проблема, с которой я столкнулся.
У меня есть AsyncTask
, который показывает прогресс DialogFragment и отклоняет его onPostExecute
. Все работает отлично, за исключением случаев, когда onPostExecute
происходит, когда приложение находится в фоновом режиме (например, нажатие кнопки "Домой" ). Затем я получил эту ошибку при отключении DialogFragment - "Can not perform this action after onSaveInstanceState
". Doh. Регулярные диалоги работают отлично. Но не FragmentDialog.
Итак, интересно, каков правильный способ отклонения DialogFragment во время работы приложения? Я не очень много работал с Фрагментами, поэтому я думаю, что я просто что-то пропустил.
DialogFragment
имеет метод под названием dismissAllowingStateLoss()
Это то, что я сделал (df == dialogFragment)
:
Убедитесь, что вы вызываете диалог таким образом:
df.show(getFragmentManager(),"DialogFragment_FLAG");
Когда вы хотите отменить диалог, выполните эту проверку:
if(df.isResumed()){
df.dismiss();
}
return;
Убедитесь, что в методе onResume() вашего фрагмента (а не df) есть следующее:
@Override
public void onResume(){
Fragment f= getFragmentManager().findFragmentByTag("DialogFragment_FLAG");
if (f!= null) {
DialogFragment df = (DialogFragment) f;
df.dismiss();
getFragmentManager().beginTransaction().remove(f).commit();
}
super.onResume();
}
Таким образом, диалог будет отклонен, если он будет виден. Если не видно, диалог будет удален далее, фрагмент станет видимым (onResume)...
Это то, что я должен был сделать, чтобы добиться того, чего вы хотите:
У меня есть функция Fragment, на которой я показывал фрагмент диалога с именем fragment_RedemptionPayment
, который объявлен глобально в верхней части. Следующий код отклоняет DialogFragment
, если он показывался до того, как действие переходит в фоновый режим и возвращается на передний план.
@Override
public void onResume() {
super.onResume();
if(fragment_RedemptionPayment.isVisible()){
fragment_RedemptionPayment.dismiss();
}
}
Решением, которое может работать, является установка Fragment.setRetainInstance(true)
в вашем диалоговом фрагменте, но это не самая красивая из исправлений.
Иногда я заметил, что мне приходится ставить в очередь мои действия с диалоговыми окнами, чтобы позволить инфраструктуре сначала восстановить состояние. Если вы можете получить текущий Looper (Activity.getMainLooper())
и обернуть это в обработчике, вы можете попробовать передать свое увольнение в обратную сторону очереди, отправив в эту очередь runnable.
Я часто использую отдельный фрагмент, который retaininstance(true)
имеет ResultReceiver
. Поэтому я передаю этот ресивер результатов своим работам и обрабатываю обратные вызовы в своем onReceive (часто в качестве маршрутизатора для других приемников). Но это может быть немного больше работы, чем это стоит, если вы используете асинхронные задачи.