J'ai commencé à utiliser DialogFragment, car ils fonctionnent bien grâce aux changements d'orientation et autres. Mais il y a un vilain problème que j'ai rencontré.
J'ai AsyncTask
qui montre la progression de DialogFragment et la rejette onPostExecute
. Tout fonctionne bien, sauf lorsque onPostExecute
se produit alors que l'application est en arrière-plan (après avoir appuyé sur le bouton Accueil, par exemple). Puis j'ai eu cette erreur lors du rejet de DialogFragment - "Can not perform this action after onSaveInstanceState
". Doh. Les dialogues réguliers fonctionnent très bien. Mais pas FragmentDialog.
Je me demande donc quelle est la bonne façon de rejeter DialogFragment alors que l'application est en arrière-plan? Je n'ai pas vraiment beaucoup travaillé avec Fragments, donc je pense que je manque juste quelque chose.
DialogFragment
a une méthode appelée dismissAllowingStateLoss()
C'est ce que j'ai fait (df == dialogFragment)
:
Assurez-vous d'appeler la boîte de dialogue de cette façon:
df.show(getFragmentManager(), "DialogFragment_FLAG");
Lorsque vous souhaitez supprimer la boîte de dialogue, effectuez cette vérification:
if (df.isResumed()){
df.dismiss();
}
return;
Assurez-vous que vous disposez des éléments suivants dans la méthode onResume () de votre fragment (pas df)
@Override
public void onResume(){
Fragment f = getFragmentManager().findFragmentByTag("DialogFragment_FLAG");
if (f != null) {
DialogFragment df = (DialogFragment) f;
df.dismiss();
}
super.onResume();
}
De cette façon, la boîte de dialogue sera fermée si elle est visible .. si elle n'est pas visible, la boîte de dialogue va être supprimée, le fragment deviendra visible (onResume) ...
Voici ce que je devais faire pour réaliser ce que vous voulez: j'ai une activité Fragment sur laquelle je montrais un fragment de dialogue nommé fragment_RedemptionPayment
qui est globalement déclaré en haut. Le code suivant rejette le DialogFragment
s'il était affiché avant que l'activité ne passe en arrière-plan et ne revienne au premier plan.
@Override
public void onResume() {
super.onResume();
if(fragment_RedemptionPayment.isVisible()){
fragment_RedemptionPayment.dismiss();
}
}
Une solution qui pourrait fonctionner consiste à définir Fragment.setRetainInstance(true)
dans votre boîte de dialogue, mais ce n'est pas la plus jolie des corrections.
Parfois, j'ai remarqué que je dois mettre en file d'attente mes actions de dialogue pour laisser le framework restaurer l'état en premier. Si vous pouvez mettre la main sur le Looper actuel (Activity.getMainLooper())
Et envelopper cela dans un gestionnaire, vous pouvez essayer de passer votre rejet à l'arrière de la file d'attente en publiant un exécutable sur cette file d'attente.
Je finis souvent par utiliser un fragment distinct qu'il retaininstance(true)
qui a un ResultReceiver
. Donc, je transmets ce récepteur de résultat à mes tâches et gère les rappels dans son onReceive (souvent comme routeur pour d'autres récepteurs). Mais cela pourrait être un peu plus de travail que cela ne vaut si vous utilisez des tâches asynchrones.