I have a DialogFragment which creates a DatePickerDialog. I'm using a static method called newInstance
to set the initial values in order to use the default empty constructor. However, how am I supposed to set the listener? After the screen rotation, when clicking in the "Done" button, the listener doesn't do anything since it does not exist.
public class DatePickerFragment extends DialogFragment {
public static final String ARG_YEAR = "year";
public static final String ARG_MONTH = "month";
public static final String ARG_DAY = "day";
private OnDateSetListener listener_;
public static DatePickerFragment newInstance(OnDateSetListener listener, int year, int month, int day) {
final DatePickerFragment date_picker = new DatePickerFragment();
date_picker.setListener(listener);
final Bundle arguments = new Bundle();
arguments.putInt(ARG_YEAR, year);
arguments.putInt(ARG_MONTH, month);
arguments.putInt(ARG_DAY, day);
date_picker.setArguments(arguments);
return date_picker;
}
private void setListener(OnDateSetListener listener) {
listener_ = listener;
}
@Override
public Dialog onCreateDialog(Bundle saved_instance_state) {
final Bundle arguments = getArguments();
final int year = arguments.getInt(ARG_YEAR);
final int month = arguments.getInt(ARG_MONTH);
final int day = arguments.getInt(ARG_DAY);
return new DatePickerDialog(getActivity(), listener_, year, month, day);
}
}
However, how am I supposed to set the listener?
You update the listener reference in the onCreate
method of the Activity
:
private OnDateSetListener mOds = new OnDateSetListener() {
@Override
public void onDateSet(DatePicker view, int year, int monthOfYear,
int dayOfMonth) {
// do important stuff
}
};
and in the onCreate
method:
if (savedInstanceState != null) {
DatePickerFragment dpf = (DatePickerFragment) getSupportFragmentManager()
.findFragmentByTag("theTag?");
if (dpf != null) {
dpf.setListener(mOds);
}
}
In my opinion there is a more efficient way of doing this, using the Fragment lifecycle. You can use the Fragment lifecycle callbacks onAttach()
and onDetach()
to automatically cast the activity as a Listener like so:
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
_listener = (OnDateSetListener)activity;
} catch(ClassCastException e) {
// check if _listener is null before using,
// or throw new ClassCastException("hosting activity must implement OnDateSetListener");
}
}
@Override
public void onDetach() {
super.onDetach();
_listener = null;
}
This technique is officially documented here
The answer of Luksprog is correct, I just want to point out, the key of the solution is the findFragmentByTag() function. Because the activity will be also recreated after screen rotation, you cannot call the setter function of its member Fragment variable, instead you should find the old fragment instance with this function.
Btw, the tag is the second parameter when you call DialogFragment.show().
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With