2012-12-19 5 views
8

J'utilise un DialogFragment pour renvoyer un DatePickerDialog dans onCreateDialog(). J'ai mis le dateSetListener à DialogFragment ("ceci" dans l'exemple ci-dessous) et tout fonctionne sauf que onDateSet() est appelé quand une rotation d'écran se produit, ce qui n'est pas souhaitable. Comment puis-je obtenir onDateSet pour ne pas être appelé lorsque l'écran est pivoté?DatePickerDialog onDateSet appelé lors de la rotation

Mon DialogFragment

public static class DateDialogFragment extends DialogFragment implements 
DatePickerDialog.OnDateSetListener{ 

    public static DateDialogFragment newInstance() { 
     return new DateDialogFragment(); 
    } 

    @Override 
    public Dialog onCreateDialog(Bundle savedInstanceState) { 
     return new DatePickerDialog(getActivity(), this, 2012, 11, 19); 
    } 

    @Override 
    public void onDateSet(DatePicker view, int year, int monthOfYear, 
     int dayOfMonth) { 
     //This is called when screen rotated, which I dont want 
     Toast.makeText(getActivity(), "Year: "+year+" Month: "+monthOfYear+" Day: "+dayOfMonth, Toast.LENGTH_SHORT).show(); 
    } 

} 

Et voilà comment je l'appelle

if(getActivity()!=null){ 
    FragmentManager fm = getActivity().getSupportFragmentManager(); 
    DialogFragment newFragment = DateDialogFragment.newInstance(); 
    newFragment.show(fm, "dialog"); 
} 
+0

Jetez un oeil à [setRetainInstance()] (http://stackoverflow.com/questions/11182180/understanding-fragments-setretaininstanceboolean) – Dmide

+0

suis-je raison ? vous ne voulez pas rappeler sur ** dateset ** méthode lorsque l'écran a tourné –

+0

Depuis la publication d'une prime sur cette question, j'ai découvert qu'il s'agit d'un doublon de http://stackoverflow.com/questions/11444238/jelly-bean- datepickerdialog-est-il-un-way-to-cancel mais je ne peux pas voter pour le fermer à cause de ma prime. –

Répondre

-1

Lorsque l'écran est mis en rotation l'activité est détruite et recréée, cela crée un nouveau fragment à chaque fois . Une façon d'éviter ce problème serait de changer l'emplacement de votre instruction if (getActivity()! = Null) dans votre code. Placez-le quelque part qui n'est pas affecté par la récréation d'activité (pas dans la méthode OnCreate).

9

Dans la méthode onDateSet, vérifiez si Activity est en cours de redémarrage en raison du changement de configuration en utilisant Activity::isChangingConfigurations. Si oui, n'affichez pas le Toast.

@Override 
public void onDateSet(android.widget.DatePicker view, int year, int monthOfYear, int dayOfMonth) { 
    if(! this.getActivity().isChangingConfigurations()) { 
     // Dialog is dismissed by user explicitly, hence show the Toast message.  
     Toast.makeText(getActivity(), "Year: "+year+" Month: "+monthOfYear+" Day: "+dayOfMonth, Toast.LENGTH_SHORT).show(); 
    } 
} 

Je l'ai testé et fonctionne parfaitement. Faites-moi savoir si une aide supplémentaire est nécessaire.

+1

Cela ne fonctionnera que lors de la modification de la configuration, mais 'onDateSet' sera également appelé lorsque l'utilisateur rejettera' DatePickerDialog' avec la touche retour. – Libin

3

Vous pouvez essayer d'utiliser un indicateur dans les rappels attachés/détachés de la boîte de dialogue. L'idée est d'annuler tout déclenchement de l'auditeur alors que la boîte de dialogue n'est pas encore attachée à la fenêtre (donc le changement ne peut venir de l'utilisateur) comme une restauration (ce qui est la raison de l'appel de l'auditeur):

// a field in the DateDialogFragment 
private boolean mShouldBeCanceled = true; // cancel the listener when this is true(the default) 

//... 
@Override 
public Dialog onCreateDialog(Bundle savedInstanceState) { 
    return new DatePickerDialog(getActivity(), this, 2012, 11, 19) { 

       @Override 
       public void onAttachedToWindow() { 
        mShouldBeCanceled = false; 
       } 

       @Override 
       public void onDetachedFromWindow() { 
        mShouldBeCanceled = true; 
       } 
    }; 
} 

et utiliser le drapeau dans l'auditeur (en raison de l'auditeur en cours d'initialisation que dans le constructeur):

@Override 
public void onDateSet(DatePicker view, int year, int monthOfYear, 
    int dayOfMonth) { 
    if (mShouldBeCanceled) { 
      return; // not a valid listener triggering 
    } 
    //This is called when screen rotated, which I dont want 
    Toast.makeText(getActivity(), "Year: "+year+" Month: "+monthOfYear+" Day: "+dayOfMonth, Toast.LENGTH_SHORT).show(); 
} 
1

Essayez de remplacer la ligne

@Override 
    public Dialog onCreateDialog(Bundle savedInstanceState) { 
     return new DatePickerDialog(getActivity(), this, 2012, 11, 19); 
    } 

par

@Override 
public Dialog onCreateDialog(Bundle savedInstanceState) { 
    super.onCreateDialog(savedInstanceState); 
} 
2

La façon dont DatePickerDialog est mis en œuvre qu'il informera le DataSet Variation onStop si OnDateSetListener est enregistré.

Vous pouvez également voir onDateSet appelé lorsque la touche Retour est pressée lorsque DatePickerDialog est affichée (non seulement l'orientation)

Raison, lorsque vous avez créé l'instance DatePickerDialog, vous avez enregistré l'auditeur de rappel.

La meilleure façon est de créer un custom Dialog qui étend DatePickerDialog et passer outre la onStop

sur mesure DatePickerDialog

private static class CustomDatePickerDialog extends DatePickerDialog{ 

    public CustomDatePickerDialog(Context context, OnDateSetListener callBack, int year, int monthOfYear, int dayOfMonth) { 
     super(context, callBack, year, monthOfYear, dayOfMonth); 
    } 

    @Override 
    protected void onStop() { 
     return; 
    } 
} 

Enfin, changer le CreateDialog à

@Override 
    public Dialog onCreateDialog(Bundle savedInstanceState) { 
     return new CustomDatePickerDialog(getActivity(), this, 2012, 11, 19); 
    } 

Cela devrait fonctionne parfaitement. Faites-moi savoir si vous voyez un problème.

0

ajouter cette propriété à votre activité dans le manifeste

android:configChanges="keyboardHidden|orientation" 
Questions connexes