web-dev-qa-db-fra.com

commitAllowingStateLoss sur DialogFragment

J'ai un IllegalStateException pour montrer un DialogFragment:

Java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState

je sais pourquoi cela se produit mais je veux utiliser commitAllowingStateLoss pour afficher la boîte de dialogue en remplaçant la fonction DialogFragment show:

public void show(FragmentManager manager, String tag) {
    mDismissed = false;
    mShownByMe = true;
    FragmentTransaction ft = manager.beginTransaction();
    ft.add(this, tag);
    ft.commit(); //replace it by commitAllowingStateLoss
}

mais je n'ai pas accès aux variables mDismissed et mShownByMe, comment puis-je accéder à ces variables pour les modifier comme l'a fait son parent.

32
Arash GM

Je pense qu'il vaut mieux utiliser IllegalStateException sur DialogFragment:

 YourDialogFragment dialogFragment = new YourDialogFragment();
 fragmentManager.beginTransaction().add(dialogFragment, YourDialogFragment.TAG_FRAGMENT).commitAllowingStateLoss();

au lieu d'utiliser show() sur DialogFragment.

38
Arash GM

La solution concernant commitAllowingStateLoss fonctionne si votre DialogFragment n'a pas d'état à enregistrer, sinon ils seront perdus comme le nom de la fonction le dit. Mais je pense que dans la plupart des cas, nous avons un état à enregistrer, c'est le principal avantage de DialogFragment: Android le recréer et maintenir son état automatiquement.

Une meilleure solution serait de vérifier si le processus de recréation est terminé, sinon de retourner à l'appelant, qui est soit une activité soit une activité de fragment, il devrait l'appeler marquer et appeler à nouveau la fonction show plus tard dans son onPostResume () ou onResumeFragments () callback, dont nous pouvons nous assurer que tous les fragments sont recréés.

Voici un show () surchargé d'une sous-classe de DialogFragment:

public boolean show(FragmentManager fragmentManager) {
   if (fragmentManager.isStateSaved()) return false;
   show(fragmentManager, tagName);
   return true;
}
5
cn123h

Fragment de la boîte de dialogue d'origine

public void show(FragmentManager manager, String tag) {
    mDismissed = false;
    mShownByMe = true;
    FragmentTransaction ft = manager.beginTransaction();
    ft.add(this, tag);
    ft.commit(); //replace it by commitAllowingStateLoss
}

Je ne connais pas les variables mDismissed, mShownByMe utilisées pour, donc il vaut mieux remplacer la méthode show(FragmentManager, String) de DialogFragment et ça marche bien avec moi

override fun show(manager: FragmentManager?, tag: String?) {
    if (manager?.isDestroyed == false && !manager.isStateSaved) {
      super.show(manager, tag)
    }
  }

isStateSaved disponible depuis appcompat> = 26.0.0 ou androidx

2
vuhung3990