android - rotacion - DialogFragment: retención del oyente después de la rotación de la pantalla
rotacion de pantalla samsung s7 (3)
Sin embargo, ¿cómo se supone que debo configurar al oyente?
Actualiza la referencia del oyente en el método onCreate
de la Activity
:
private OnDateSetListener mOds = new OnDateSetListener() {
@Override
public void onDateSet(DatePicker view, int year, int monthOfYear,
int dayOfMonth) {
// do important stuff
}
};
y en el método onCreate
:
if (savedInstanceState != null) {
DatePickerFragment dpf = (DatePickerFragment) getSupportFragmentManager()
.findFragmentByTag("theTag?");
if (dpf != null) {
dpf.setListener(mOds);
}
}
Tengo un DialogFragment que crea un DatePickerDialog. Estoy usando un método estático llamado newInstance
para establecer los valores iniciales para usar el constructor vacío predeterminado. Sin embargo, ¿cómo se supone que debo configurar al oyente? Después de la rotación de la pantalla, al hacer clic en el botón "Listo", el oyente no hace nada ya que no existe.
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);
}
}
En mi opinión, hay una manera más eficiente de hacerlo, utilizando el ciclo de vida de Fragment. Puede utilizar las devoluciones de llamada del ciclo de vida de Fragment onAttach()
y onDetach()
para convertir automáticamente la actividad como un Listener de esta forma:
@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;
}
Esta técnica está oficialmente documentada here
La respuesta de Luksprog es correcta, solo quiero señalar que la clave de la solución es la función findFragmentByTag (). Debido a que la actividad también se volverá a crear después de la rotación de la pantalla, no se puede llamar a la función setter de su variable miembro Fragment, sino que se debe buscar la instancia antigua de fragmento con esta función.
Por cierto, la etiqueta es el segundo parámetro cuando llamas a DialogFragment.show ().