Tengo un fragmento que abre un Dialogfragment
para obtener la entrada del usuario (una cadena y un entero). ¿Cómo envío estas dos cosas al fragmento?
Aquí está mi DialogFragment:
public class DatePickerFragment extends DialogFragment { String Month; int Year; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { getDialog().setTitle(getString(R.string.Date_Picker)); View v = inflater.inflate(R.layout.date_picker_dialog, container, false); Spinner months = (Spinner) v.findViewById(R.id.months_spinner); ArrayAdapter monthadapter = ArrayAdapter.createFromResource(getActivity(), R.array.Months, R.layout.picker_row); months.setAdapter(monthadapter); months.setOnItemSelectedListener(new OnItemSelectedListener(){ @Override public void onItemSelected(AdapterView parentView, View selectedItemView, int monthplace, long id) { Month = Integer.toString(monthplace); } public void onNothingSelected(AdapterView parent) { } }); Spinner years = (Spinner) v.findViewById(R.id.years_spinner); ArrayAdapter yearadapter = ArrayAdapter.createFromResource(getActivity(), R.array.Years, R.layout.picker_row); years.setAdapter(yearadapter); years.setOnItemSelectedListener(new OnItemSelectedListener(){ @Override public void onItemSelected(AdapterView parentView, View selectedItemView, int yearplace, long id) { if (yearplace == 0){ Year = 2012; }if (yearplace == 1){ Year = 2013; }if (yearplace == 2){ Year = 2014; } } public void onNothingSelected(AdapterView parent) {} }); Button button = (Button) v.findViewById(R.id.button); button.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { getDialog().dismiss(); } }); return v; } }
Necesito enviar los datos después de hacer clic en el botón y antes de getDialog().dismiss()
Aquí está el fragmento al que los datos deben enviarse:
public class CalendarFragment extends Fragment { int Year; String Month; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { super.onCreate(savedInstanceState); int position = getArguments().getInt("position"); String[] categories = getResources().getStringArray(R.array.categories); getActivity().getActionBar().setTitle(categories[position]); View v = inflater.inflate(R.layout.calendar_fragment_layout, container, false); final Calendar c = Calendar.getInstance(); SimpleDateFormat month_date = new SimpleDateFormat("MMMMMMMMM"); Month = month_date.format(c.getTime()); Year = c.get(Calendar.YEAR); Button button = (Button) v.findViewById(R.id.button); button.setText(Month + " "+ Year); button.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { new DatePickerFragment().show(getFragmentManager(), "MyProgressDialog"); } }); return v; } }
así que una vez que el usuario selecciona una fecha en el Dialogfragment
, debe devolver el mes y el año.
Luego, el texto en el botón debe cambiar al mes y año especificado por el usuario.
NOTA: aparte de una o dos llamadas específicas de Fragmento, esta es una receta de enfoque genérica para la implementación del intercambio de datos entre componentes débilmente acoplados. Puede utilizar este enfoque de forma segura para intercambiar datos entre literalmente cualquier cosa, ya sea Fragmentos, Actividades, Diálogos o cualquier otro componente de su aplicación.
Aquí está la receta:
interface
(es decir, llamada MyContract
) que contiene una firma del método que se utilizará para pasar los datos, es decir, methodToPassData(... data);
. DialogFragment
implemente su contrato: class MyFragment extends Fragment implements MyContract {....}
DialogFragment
establezca su Fragment
invocación como fragmento de destino myDialogFragment.setTargetFragment(this, 0);
llamando a myDialogFragment.setTargetFragment(this, 0);
. Este es el objeto con el que hablarás más tarde. DialogFragment
, obtenga ese fragmento de invocación llamando a getTargetFragment();
y lanzar el objeto devuelto a la interfaz de contrato que creó en el paso 1, haciendo: MyContract mHost = (MyContract)getTargetFragment();
. Este paso garantiza que su objective implemente el contrato que necesita (tenga en cuenta que obtendrá ClassCastException
si su fragmento de destino no está implementando la interfaz de MyContract
). Esto normalmente no debería suceder, a menos que esté haciendo demasiado copiar y pegar-encoding :). Si su proyecto utiliza un código externo, bibliotecas o complementos, etc., en ese caso debería detectar la excepción y decirle al usuario, es decir, el complemento no es compatible en lugar de bloquearse. methodToPassData()
sobre el objeto que obtuvo anteriormente: ((MyContract)getTargetFragment()).methodToPassData(data);
. Si su onAttach()
ya arroja y asigna un fragmento de destino a una variable de clase (es decir, mHost
), este código sería simplemente mHost.methodToPassData(data);
. Acaba de pasar satisfactoriamente sus datos del diálogo a invocar fragmento.
Aquí hay otra receta sin usar ninguna interfaz. Solo haciendo uso de setTargetFragment
y Bundle
para pasar datos entre DialogFragment y Fragment.
public static final int DATEPICKER_FRAGMENT = 1; // class variable
1. Llame al DialogFragment
como se muestra a continuación:
// create dialog fragment DatePickerFragment dialog = new DatePickerFragment(); // optionally pass arguments to the dialog fragment Bundle args = new Bundle(); args.putString("pickerStyle", "fancy"); dialog.setArguments(args); // setup link back to use and display dialog.setTargetFragment(this, DATEPICKER_FRAGMENT); dialog.show(getFragmentManager().beginTransaction(), "MyProgressDialog")
2. Use el Bundle
adicional en una Intent
en el DialogFragment
para pasar cualquier información al fragmento de destino. El código siguiente en Button#onClick()
evento Button#onClick()
de DatePickerFragment
pasa un String e Integer.
Intent i = new Intent() .putExtra("month", getMonthString()) .putExtra("year", getYearInt()); getTargetFragment().onActivityResult(getTargetRequestCode(), Activity.RESULT_OK, i); dismiss();
3. Use el método CalendarFragment
onActivityResult()
para leer los valores:
@Override public void onActivityResult(int requestCode, int resultCode, Intent data) { switch (requestCode) { case DATEPICKER_FRAGMENT: if (resultCode == Activity.RESULT_OK) { Bundle bundle = data.getExtras(); String mMonth = bundle.getString("month", Month); int mYear = bundle.getInt("year"); Log.i("PICKER", "Got year=" + year + " and month=" + month + ", yay!"); } else if (resultCode == Activity.RESULT_CANCELED) { ... } break; } }