Правильный способ отклонения DialogFragment, пока приложение находится в фоновом режиме - PullRequest
62 голосов
/ 17 февраля 2012

Я начал использовать DialogFragment, потому что они хорошо работают через изменения ориентации и прочее. Но есть неприятная проблема, с которой я столкнулся.

У меня есть AsyncTask, который показывает прогресс DialogFragment и отклоняет его onPostExecute. Все работает нормально, кроме случаев, когда onPostExecute происходит, когда приложение находится в фоновом режиме (например, после нажатия кнопки «Домой»). Затем я получил эту ошибку при отклонении DialogFragment - "Can not perform this action after onSaveInstanceState". Doh. Обычные диалоги работают просто отлично. Но не FragmentDialog.

Итак, мне интересно, как правильно закрыть DialogFragment, пока приложение находится в фоновом режиме? Я не очень много работал с Фрагментами, поэтому думаю, что мне чего-то не хватает.

Ответы [ 4 ]

132 голосов
/ 23 апреля 2012

DialogFragment имеет метод с именем dismissAllowingStateLoss()

11 голосов
/ 21 февраля 2013

Это то, что я сделал (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();
  }
  super.onResume();
}   

Таким образом, диалог будет закрыт, если он виден .. еслине видно диалоговое окно будет закрыто после того, как фрагмент станет видимым (onResume) ...

3 голосов
/ 16 апреля 2017

Это то, что я должен был сделать, чтобы достичь того, чего вы хотите: у меня есть операция «Фрагмент», в которой я показываю фрагмент диалога с именем fragment_RedemptionPayment, который глобально объявлен вверху.Следующий код отклоняет DialogFragment, если он показывался до того, как действие переходит в фоновый режим и возвращается на передний план.

     @Override
        public void onResume() {
            super.onResume();        
            if(fragment_RedemptionPayment.isVisible()){
                fragment_RedemptionPayment.dismiss();
            }
}
0 голосов
/ 17 февраля 2012

Решением, которое может сработать, является установка Fragment.setRetainInstance(true) в вашем диалоговом фрагменте, но это не самое красивое из исправлений.

Иногда я замечал, что мне приходится ставить в очередь свои диалоговые действия, чтобы инфраструктура сначала восстановила состояние. Если вы можете получить текущий Looper (Activity.getMainLooper()) и обернуть его в обработчике, вы можете попробовать передать свое увольнение в конец очереди, разместив в этой очереди работоспособный объект.

Я часто заканчиваю тем, что использую отдельный фрагмент, который retaininstance(true) имеет ResultReceiver. Таким образом, я передаю этот получатель результатов своим заданиям и обрабатываю обратные вызовы в его onReceive (часто в качестве маршрутизатора для других получателей). Но это может быть немного больше работы, чем стоит, если вы используете асинхронные задачи.

...