2014-07-18 2 views
1

Cette boîte de dialogue assez simple se ferme après la rotation de l'écran alors que setRetainInstance a la valeur true. Des idées quoi de mal?DialogFragment disparaît à la rotation de l'écran

public class StreetDialog extends DialogFragment { 

    public static StreetDialog newInstance(String[] values) { 
     StreetDialog f = new StreetDialog(); 
     Bundle args = new Bundle(); 
     args.putStringArray("values", values); 
     f.setArguments(args); 
     return f; 
    } 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setRetainInstance(true); 
    } 

    @Override 
    public Dialog onCreateDialog(Bundle savedInstanceState) { 

     final String[] values = getArguments().getStringArray("values"); 

     AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); 
     //build my dialog 
     return builder.create(); 
    } 

    @Override 
    public void onDestroyView() { 
     if (getDialog() != null && getRetainInstance()) 
      getDialog().setDismissMessage(null); 

     super.onDestroyView(); 
    } 
} 
+0

Si je me souviens bien, c'est le comportement normal. Je fournis généralement une balise à la méthode show, et lorsque l'onCreate de l'Activity est appelée à nouveau, je recherche la balise. Si le fragment! = Null, je crée une nouvelle instance et la montre à nouveau – Blackbelt

+0

@blackbelt mais fragment! = Null suppose qu'il existe déjà un fragment avec une telle balise. Si vous ajoutez à nouveau le même fragment, l'ancien fragment sera-t-il toujours dans la hiérarchie de vue? –

+0

oui c'est le cas. Je l'enlève, avant d'en montrer un nouveau, car vous avez besoin du gestionnaire de fragment pour montrer le fragment de dialogue et je ne sais pas s'il est lié à l'instance de l'activité, – Blackbelt

Répondre

2

Si je me souviens est correctement le comportement normal. Je fournis généralement une balise à la méthode show, et lorsque l'onCreate de l'Activity est appelée à nouveau, je recherche la balise. Si le fragment! = Null je l'enlève, avant de créer et d'afficher le nouveau. Dans le code, ce que je fais habituellement est:

Fragment fragment = getSupportFragmentManager().findFragmentByTag(FRAGMENT_TAG); 
if (fragment != null) { 
    getSupportFragmentManager().beginTransaction().remove(fragment).commit(); 
} 
new CustomDialogFragment().show(getSupportFragmentManager(), FRAGMENT_TAG); 
0

C'est une question que je crois que la meilleure façon de résoudre et en utilisant une approche ci-dessous:

Créer une méthode statique pour initialiser une boîte de dialogue, se rappelant que c'est une bonne pratique puisque nous avons toujours Le constructeur par défaut et l'ensemble stockent l'état du fragment. Dans la méthode onCreateDialog, initialisez AlertDialog avec les données transmises dans la "méthode constructeur". Dans votre activité, vous pouvez implémenter une interface (car nous ne pouvons pas conserver la référence car elle a peut-être été détruite lors de la rotation de l'appareil). Pour ouvrir la boîte de dialogue, , vérifiez qu'elle a été ajoutée à FragmentManager.

voir plus ici (lien en portugais - br): http://nglauber.blogspot.com.br/2013_10_01_archive.html

public class SimpleDialog extends DialogFragment implements OnClickListener { 

    private static final String EXTRA_ID  = "id"; 
    private static final String EXTRA_MESSAGE = "message"; 
    private static final String EXTRA_TITLE = "title"; 
    private static final String EXTRA_BUTTONS = "buttons"; 
    private static final String DIALOG_TAG = "SimpleDialog"; 

    private int dialogId; 

    public static SimpleDialog newDialog(int id, 
    String title, String message, int[] buttonTexts){ 
    // Using the Bundle to save state 
    Bundle bundle = new Bundle(); 
    bundle.putInt(EXTRA_ID, id); 
    bundle.putString(EXTRA_TITLE, title); 
    bundle.putString(EXTRA_MESSAGE, message); 
    bundle.putIntArray(EXTRA_BUTTONS, buttonTexts); 

    SimpleDialog dialog = new SimpleDialog(); 
    dialog.setArguments(bundle); 
    return dialog; 
    } 

    @Override 
    public Dialog onCreateDialog(Bundle savedInstanceState) { 

    String title = getArguments() .getString(EXTRA_TITLE); 
    String message = getArguments().getString(EXTRA_MESSAGE); 
    int[] buttons = getArguments().getIntArray(EXTRA_BUTTONS); 

    AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(getActivity()); 
    alertDialogBuilder.setTitle(title); 
    alertDialogBuilder.setMessage(message); 

    switch (buttons.length) { 
     case 3: 
     alertDialogBuilder.setNeutralButton(buttons[2], this); 

     case 2: 
     alertDialogBuilder.setNegativeButton(buttons[1], this); 

     case 1: 
     alertDialogBuilder.setPositiveButton(buttons[0], this); 
    }  
    return alertDialogBuilder.create(); 
    } 

    @Override 
    public void onClick(DialogInterface dialog, int which) { 
    // Your Activity must to implements this interface 
    ((FragmentDialogInterface)getActivity()).onClick(dialogId, which); 
    } 

    public void openDialog(FragmentManager supportFragmentManager) { 

    if (supportFragmentManager.findFragmentByTag(DIALOG_TAG) == null){ 
     show(supportFragmentManager, DIALOG_TAG); 
    }  
    } 
    // Interface that was invoked by clicking the button 
    public interface FragmentDialogInterface { 
    void onClick(int id, int which); 
    } 

Pour ouvrir la boîte de dialogue dans votre activité

public void openSimpleDialog(View v) { 
    SimpleDialog dialog = SimpleDialog.newDialog( 
    0,    // Id from dialog 
    "Alert",  // title 
    "Message",  // menssage 
    new int[]{  // texts from buttons 
     android.R.string.ok, 
     android.R.string.cancel }); 
    dialog.openDialog(getSupportFragmentManager()); 
    } 

    @Override 
    public void onClick(int id, int which) { 
    Toast.makeText(MainActivity.this, 
     "Button clicked"+ which, Toast.LENGTH_SHORT) 
     .show(); 
    } 
Questions connexes