DialogFragment - сохранение слушателя после поворота экрана
У меня есть DialogFragment, который создает DatePickerDialog. Я использую статический метод под названием newInstance
, чтобы установить начальные значения, чтобы использовать пустой конструктор по умолчанию. Однако, как я должен установить слушателя? После поворота экрана при нажатии кнопки "Готово" слушатель ничего не делает, поскольку он не существует.
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);
}
}
Ответы
Ответ 1
Однако, как я должен установить слушателя?
Вы обновляете ссылку слушателя в методе onCreate
Activity
:
private OnDateSetListener mOds = new OnDateSetListener() {
@Override
public void onDateSet(DatePicker view, int year, int monthOfYear,
int dayOfMonth) {
// do important stuff
}
};
и в методе onCreate
:
if (savedInstanceState != null) {
DatePickerFragment dpf = (DatePickerFragment) getSupportFragmentManager()
.findFragmentByTag("theTag?");
if (dpf != null) {
dpf.setListener(mOds);
}
}
Ответ 2
По-моему, существует более эффективный способ сделать это, используя жизненный цикл фрагмента. Вы можете использовать обратные вызовы жизненного цикла фрагмента onAttach()
и onDetach()
для автоматического включения активности в качестве слушателя:
@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;
}
Этот метод официально зарегистрирован здесь
Ответ 3
Ответ Luksprog верен, я просто хочу указать, ключом решения является функция findFragmentByTag(). Поскольку активность будет также воссоздана после поворота экрана, вы не сможете вызвать функцию setter ее переменной-член Fragment, вместо этого вы должны найти экземпляр старого фрагмента с этой функцией.
Btw, тег является вторым параметром при вызове DialogFragment.show().