Fragment之间的值传递

适用场景

有两个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();
        }
    }

你可能感兴趣的:(学习笔记)