适用场景
有两个Fragmnet:CrimeFragment和DatePickerFragment
需求:CrimeFragment打开DatePickerFragment,并获取到DatePickerFragment中的结果,类似于Activity的 startActivityForResult(...)方法.
设置目标Fragment
类似activity之间的关联,可将CrimeFragment设置成DatePickerFragment的目标Fragment,
即使在CrimeFragment和DatePickerFragment被销毁或重建后,操作系统也会重新关联他们,调用以下方法可以创建这种关联.
public void setTargetFragment(Fragment fragment, int requestCode)
该方法有两个参数:目标fragment 和 类似于 startActivityForResult(...)方法的请求代码.需要时,目标Fragment使用请求代码来确定是哪个fragment在回传数据.
目标fragment的请求代码由FragmentManager负责跟踪管理,我们可以调用fragment(设置目标fragment的fragment) 的getTargetFragment()和getTargetRequestCode()方法获取它们.
在CrimeFragment 中创建请求代码常量,然后将CrimeFragment设置为DatePickerFragment实例的目标fragment.
private static final int REQUEST_CODE = 0;
...
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_crime, container, false);
mDate = (Button) view.findViewById(R.id.crime_date);
mDate.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
DatePickerFragment picker = DatePickerFragment.newInstance(mCrime.getDate());
FragmentManager manager = getFragmentManager();
picker.setTargetFragment(CrimeFragment.this, REQUEST_CODE);
picker.show(manager, DIALOG_DATE);
}
});
}
传递数据给目标Fragment
建立CrimeFragment与DatePickerFragment间的联系后,需要将数据回传给CrimeFragment.回传日期将作为extra附加给Intent.
调用CrimeFragment.onActivityResult(...)方法,发送信息.
Activity.onActivityResult(...)方法是ActivityManager在子activity 销毁后调用的父activity方法. 处理activity间的数据返回时,ActivityManager会自动调用Activity.onActivityResult()方法,父activity在接到Activity.onActivityResult(...) 方法的调用后,其FragmentManager会调用对应的fragment的Fragment.onActivityResult(...) 方法.
处理由同一个activity托管的两个fragment间的数据返回时,可借用Fragment.onActivityResult(...)方法. 因此,直接调用目标fragment.onActivityResult(...)方法,就能实现数据的回传.该方法恰好有我们需要的如下信息:
请求代码: 与传入setTargetFragment(...)方法相匹配,告诉目标fragment返回结果来自哪里.
结果代码: 决定下一步该采取什么行动.
Intent: 包含extra数据
在DatePickerFragment类中,新建sendResult(...)私有方法,创建Intent并将日期数据作为extra附加到Intent, 最后调用CrimeFragment.onActivityResult().
上代码:
public static final String EXTRA_DATE = "com.crimeintent.date";
...
private void sendResult(int requestCode, Date date) {
if (getTargetFragment()==null){
return;
}
Intent intent = new Intent();
intent.putExtra(EXTRA_DATE, date);
getTargetFragment().onActivityResult(getTargetRequestCode(),requestCode,intent);
}
方法调用:
new AlertDialog.Builder(getActivity())
.setView(view)
.setTitle(R.string.date_picker_title)
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
int year = mDatePicker.getYear();
int month = mDatePicker.getMonth();
int day = mDatePicker.getDayOfMonth();
Date date= new GregorianCalendar(year,month,day).getTime();
sendResult(Activity.RESULT_OK,date);
}
})
.create();
在CrimeFragment 方法中获取数据
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode!= Activity.RESULT_OK){
return;
}
if (requestCode==REQUEST_CODE){
Date date = (Date)data.getSerializableExtra(DatePickerFragment.EXTRA_DATE);
mCrime.setDate(date);
updateDate();
}
}