项目中的逻辑结构图
主要思想:
- 要传递crime 的日期给DatePickerFragment,需新建一个newInstance(Date)方法,然后将Date作为 argument 附加给 fragment。
- 要将新日期返回给CrimeFragment, 并更新模型层以及对应的视图,需将日期打包为extra并附加到Intent,然后调用CrimeFragment.onActivityResult(…)方法,并传入准备好的Intent参数
argument回顾
在之前Activity 和 Fragment 传值的过程中,我们使用了 Argument,下面我们回顾一下我们是如何使用它的。
为满足以上要求,通常添加名为 newInstance() 的静态方法给 Fragment类。使用该方法,完成fragment实例及Bundle对象的创建,然后将argument 放入bundle中,最后附加给fragment。
托管activity需要fragment实例时,转而调用newInstance() 方法,而非直接调用其构造函数。并且,为满足fragment创建argument的要求,activity可给newInstance()传入任何需要的参数
传值
那么,fragment之间传值同样也需要借助argument
1 | //DatePickerFragment 中的 newInstance 方法,返回一个DPF实例 |
当然,与之对应,在 CrimeFragment 中创建 dialog 语句也要改成调用 newInstance 的形式
1 | //CrimeFragment 中点击事件开启DatePickerFragment |
另外,这里的Date不能直接被 DatePickerFragment 所识别,我们需要对 DatePickerFragment 所接收到的 Date 进行处理,当然这不是重点,这里不展开。
返回更新数据
首先,我们要弄清这两个fragment之间的关系。如果是activity的数据回传,我们调用startActivityForResult(…)方法,ActivityManager负责跟踪管理activity父子关系。回传数据后,子activity被销毁,但ActivityManager知道接收数据是哪个activity。
设置目标fragment(关联)
可将CrimeFragment设置成DatePickerFragment的Target fragment。
这样,在CrimeFragment 和 DatePickerFragment 被销毁并重建后,操作系统会重新关联他们。调用以下方法可建立这种关联
1 | public void setTargetFragment(Fragment fragment, int requestCode) |
在CrimeFragment 中,创建请求代码常量,然后将CrimeFragment设为DatePickerFragment 实例的目标fragment1
2
3
4
5
6
7
8
9
10private static final int REQUEST_DATE = 0;
//在onCreatView中设置按钮监听器
public void onClick(View view) {
FragmentManager manager = getFragmentManager();
DatePickerFragment dialog = DatePickerFragment.newInstance(mCrime.getDate());
dialog.setTargetFragment(CrimeFragment.this, REQUEST_DATE);
dialog.show(manager, DIALOG_DATE);
}
传递数据给目标fragment(传值)
处理有同一个activity托管的两个fragment之间的数据返回时,可借用Fragment.onActivityResult(…)方法。因此,直接调用目标fragment的Fragment.onActivityResult(…)方法,就能实现数据回传。需要以下信息:
- 请求代码:与传入 setTargetFragment(…) 方法的代码相匹配,告诉目标 fragment 返回结果来自哪里
- 结果代码:决定下一步该采取什么行动
- Intent:包含extra数据
我们来看一下具体怎么做的
1 |
|
随后,我们将 DatePickerFragment 的确定按钮点击事件修改为调用sendResult(…)方法
1 | return new AlertDialog.Builder(getActivity()) |
最后,在CrimeFragment接收数据
1 |
|