java - from - dialogfragment kotlin
¿Cómo enviar datos desde DialogFragment a un Fragment? (2)
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;
}
}
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<CharSequence> 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<CharSequence> 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:
- Crear
interface
(es decir, llamadaMyContract
) que contiene una firma del método que se utilizará para pasar los datos, es decir,methodToPassData(... data);
. - Asegúrese de que su
DialogFragment
implemente su contrato:class MyFragment extends Fragment implements MyContract {....}
- Al crear
DialogFragment
establezca suFragment
invocación como fragmento de destinomyDialogFragment.setTargetFragment(this, 0);
llamando amyDialogFragment.setTargetFragment(this, 0);
. Este es el objeto con el que hablarás más tarde. - En su
DialogFragment
, obtenga ese fragmento de invocación llamando agetTargetFragment();
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 objetivo implemente el contrato que necesita (tenga en cuenta que obtendráClassCastException
si su fragmento de destino no está implementando la interfaz deMyContract
). Esto normalmente no debería suceder, a menos que esté haciendo demasiado copiar y pegar-codificación :). 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. - Cuando llegue el momento de devolver los datos, llame a
methodToPassData()
sobre el objeto que obtuvo anteriormente:((MyContract)getTargetFragment()).methodToPassData(data);
. Si suonAttach()
ya arroja y asigna un fragmento de destino a una variable de clase (es decir,mHost
), este código sería simplementemHost.methodToPassData(data);
. - Voilà.
Acaba de pasar satisfactoriamente sus datos del diálogo a invocar fragmento.