Подтвердить что ты не робот

Правильный способ отклонения DialogFragment во время приложения в фоновом режиме

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

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

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

4b9b3361

Ответ 1

DialogFragment имеет метод под названием dismissAllowingStateLoss()

Ответ 2

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

Ответ 3

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

     @Override
        public void onResume() {
            super.onResume();        
            if(fragment_RedemptionPayment.isVisible()){
                fragment_RedemptionPayment.dismiss();
            }
}

Ответ 4

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

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

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