I am using a DialogFragment to return a DatePickerDialog in onCreateDialog(). I have set the dateSetListener to be the DialogFragment (“this” in example below) and everything works except that onDateSet() is called when a screen rotation occurs, which is undesirable. How can I get onDateSet to not be called when the screen is rotated?
My 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();
}
}
And this is how I call it
if(getActivity()!=null){
FragmentManager fm = getActivity().getSupportFragmentManager();
DialogFragment newFragment = DateDialogFragment.newInstance();
newFragment.show(fm, "dialog");
}
In onDateSet
method, check whether Activity
is being restarted due to the configuration change by using Activity::isChangingConfigurations. If yes, then don’t display the 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();
}
}
I’ve tested it and works perfectly. Let me know if any further help is required.
Answer:
You could try using a flag in the attached/detached callbacks of the dialog. The idea is to cancel any triggering of the listener while the dialog isn’t yet attached to the window(so the change can’t possible come from the user) like a restore(which I think is the reason for the listener being called again):
// 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;
}
};
}
and use the flag in the listener(due to the listener being initialized only in the constructor):
@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();
}
Answer:
The way DatePickerDialog
is implemented that it will notify the DataSet
Change in onStop
if OnDateSetListener
is registered.
You could also see onDateSet
called when Back key is pressed when DatePickerDialog
is Shown(not only orientation)
Reason, when you created the DatePickerDialog
instance , you have registered the callback listener.
So the best way is to create a custom Dialog
which extends DatePickerDialog
and override the onStop
Custom 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;
}
}
Finally , change the CreateDialog
to
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
return new CustomDatePickerDialog(getActivity(), this, 2012, 11, 19);
}
This should work perfectly. Let me know if you see any issue.
Answer:
Try to replace the line
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
return new DatePickerDialog(getActivity(), this, 2012, 11, 19);
}
by
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
super.onCreateDialog(savedInstanceState);
}
Answer:
add this property to your activity in manifest
android:configChanges="keyboardHidden|orientation"
Answer:
When the screen is rotated the activity is destroyed and recreated, this creates a new fragment each time. One way to avoid this problem would be to change the placement of your if(getActivity()!=null) statement in your code. Place it somewhere that is not affected by the activity recreation (not in the OnCreate method).
Tags: androidandroid, date