如何将数据从DialogFragment发送到片段?

我有一个片段打开一个Dialogfragment获取用户input(一个string和一个整数)。 我如何将这两件事发回给片段?

这是我的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; } } 

我需要在点击button之后和getDialog().dismiss()之前发送数据getDialog().dismiss()

这是数据需要发送到的片段:

 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; } } 

所以一旦用户在Dialogfragmentselect了一个date,就必须返回月份和年份。

然后,button上的文本应该更改为用户指定的月份和年份。

注意:除了一个或两个Fragment特定的调用外,这是一个通用的方法,用于实现松耦合组件之间数据交换的API。 您可以安全地使用这种方法在碎片,活动,对话框和应用程序的任何其他组件之间交换数据。


这是配方:

  1. 创buildInterface (即MyDialogCallbackContract )的方法将用于传回你需要的数据callback用Fragment (即methodToPassDataBackToFragment(... data); )。
  2. 确保您的DialogFragment符合该合同: class MyFragment extends Fragment implements MyDialogCallbackContract {....}
  3. 在创buildDialogFragment通过调用myDialogFragment.setTargetFragment(this, 0);将调用Fragment设置为DialogFragment的目标 myDialogFragment.setTargetFragment(this, 0);
  4. 在你的DialogFragment ,调用getTargetFragment(); 并通过执行以下操作将返回的对象转换为您在步骤1中创build的合同接口: MyDialogCallbackContract mHost = (MyDialogCallbackContract)getTargetFragment(); 。 这一步可以确保您的目标实现您所需要的合同,然后您可以安全地调用合同的方法来处理您的数据。 注意,如果你的目标片段没有实现MyDialogCallbackContract接口,你将得到ClassCastException ,除非你做了太多的复制和粘贴代码,或者你的项目可能使用外部代码,库,插件等,情况下,你应该赶上例外,并告诉用户即插件不兼容)
  5. 当时间到了,调用methodToPassData()来传递你想要的数据,就像这样((MyDialogCallbackContract)getTargetFragment()).methodToPassDataBackToFragment(data); 。 如果你已经将onAttach()中的目标片段赋值给一个variables(即mHost ),那么这个代码就是mHost.methodToPassDataBackToFragment(data);
  6. 瞧。 您只是成功地将您的数据从对话框传回到调用片段。

这是另一个配方,不使用任何接口。 只需使用setTargetFragmentBundle在DialogFragment和Fragment之间传递数据即可。

 public static final int DATEPICKER_FRAGMENT = 1; // class variable 

1.如下所示调用DialogFragment

 // 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.在DialogFragmentIntent中使用额外的Bundle将任何信息传递回目标片段。 DatePickerFragment Button#onClick()事件中的下面的代码传递一个String和Integer。

 Intent i = new Intent() .putExtra("month", getMonthString()) .putExtra("year", getYearInt()); getTargetFragment().onActivityResult(getTargetRequestCode(), Activity.RESULT_OK, i); dismiss(); 

3.使用CalendarFragmentonActivityResult()方法读取值:

 @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; } }