With help from a friend I now have a solution to this problem. The short version is: Make the DateDialogFragment parcelable and save the fragment on orientation change. Recreate the listener every time onCreate in the calling class runs. As you can see the showDatePickerDialog() is changed so that the creation of the listener is moved out of it.
Here are some snippets, starting with the calling class:
DateDialogFragment frag;
DateDialogFragment.DateDialogFragmentListener mListener;
private EditText birthdate;
private Calendar now;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mListener = new DateDialogFragment.DateDialogFragmentListener() {
@Override
public void updateChangedDate(int year, int month, int day) {
now.set(year, month, day);
pet.setBirthdate(now.getTimeInMillis());
birthdate = (EditText) findViewById(R.id.birth_day_et);
birthdate.setText(pet.getBirthdateInText());
}
};
if (savedInstanceState != null) {
pet.setBirthdate(savedInstanceState.getLong("birthday"));
now = (Calendar) savedInstanceState.getSerializable("n");
if (now != null) {
frag = (DateDialogFragment) savedInstanceState.getParcelable("frag");
frag.setListener(mListener);
}
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putLong("birthday", pet.getBirthdateInMillis());
outState.putSerializable("n", now);
outState.putParcelable("frag", frag);
}
}
public void showDatePickerDialog() {
now = Calendar.getInstance();
frag = DateDialogFragment.newInstance(this, mListener, now);
frag.show(getSupportFragmentManager(), "DateDialogFragment");
}
And here are the changes to the DateDialogFragment class. Except from what's written below the class looks the same as in my question.
public class DateDialogFragment extends SherlockDialogFragment implements Parcelable {
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel arg0, int arg1) {
}
public static void setListener(DateDialogFragmentListener listener) {
mListener = listener;
}
The solution to recreate the listener in the calling class may not be the prettiest possible but at least it works. I hope this will be useful to someone. :)