同一activity托管的两个fragment间的数据传递与返回

创建DatePickerFragment

/**
 * 使用DialogFragment(AlterDialog视图封装在DialogFragment中)而不使用AlertDialog,
 * 这是Android开发原则推荐。 使用FragmentManager管理对话框,可使用更多配置选项来显示对话框。
 * 另外,如果设备发生旋转,独立配置使用的AlterDialog会在旋转后消失
 * ,而配置封装在DialogFragment中的AlertDialog则不会有此问题。
 */
public class DatePickerFragment extends DialogFragment {
    public static final String EXTRA_DATE = "com.huangfei.criminalintent.date";
    private Date mDate;

    public static DatePickerFragment newInstance(Date date) {
        Bundle bundle = new Bundle();
        bundle.putSerializable(EXTRA_DATE, date);

        DatePickerFragment fragment = new DatePickerFragment();
        fragment.setArguments(bundle);
        return fragment;
    }

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        mDate = (Date) getArguments().getSerializable(EXTRA_DATE);

        /**
         * DatePickerFragment需要使用Date中的信息来初始化DatePicker对象。然而,
         * DatePicker对象的初始化需要整数形式的月、日、年。
         * Date就是个时间戳,它无法直接提供整数形式的月、日、年。需先创建一个Calendar对象
         * ,然后用Date对象对其进行配置,即可从Calendar对 象中取回所需信息。
         */
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(mDate);
        int year = calendar.get(Calendar.YEAR);
        int month = calendar.get(Calendar.MONTH);
        int day = calendar.get(Calendar.DAY_OF_MONTH);

        View view = getActivity().getLayoutInflater().inflate(
                R.layout.dialog_date, null);

        DatePicker datePicker = (DatePicker) view
                .findViewById(R.id.dialog_date_datePicker);
        datePicker.init(year, month, day, new OnDateChangedListener() {

            @Override
            public void onDateChanged(DatePicker view, int year,
                    int monthOfYear, int dayOfMonth) {
                mDate = new GregorianCalendar(year, monthOfYear, dayOfMonth)
                        .getTime();

                /**
                 * 为防止设备旋转时发生Date数据的丢失,在onDateChanged(...)方法的尾部,
                 * 我们将Date对象回写保存到了fragment argument中。
                 */
                getArguments().putSerializable(EXTRA_DATE, mDate);
            }
        });

        /**
         * Android有3种可用于对话框的按钮:positive按钮、negative按钮、neutral按钮
         */
        return new AlertDialog.Builder(getActivity())
                .setTitle(R.string.date_picker_title)// 设置对话框标题
                .setView(view)// 设置对话框布局
                .setPositiveButton(android.R.string.ok, new OnClickListener() {

                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        sendResult(Activity.RESULT_OK);
                    }
                })// 设置对话框按钮
                .create();
    }
}

设置目标Fragment

mDateButton.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                FragmentManager fm = getActivity().getSupportFragmentManager();
                DatePickerFragment dialog = DatePickerFragment.newInstance(mCrime.getDate());
                /**
                 * 同一Activity中,为了使CrimeFragment能够接受到DatePickerFragment返回的数据,可将CrimeFragment设置为
                 * DatePickerFragment的目标fragment,可调用方法:
                 * Fragment.setTargetFragment(Fragment, requestCode);
                 * 
                 * 目标fragment以及请求码由FragmentManager负责跟踪记录,我们可调用fragment(设置目标fragment的fragment)的
                 * getTargetFragment()与getTargetRequestCode()方法获取它们。
                 */
                dialog.setTargetFragment(CrimeFragment.this, REQUEST_DATE);
                /**
                 * 要将DialogFragment添加给FragmentManager管理并放置到屏幕上,可调用DialogFragment实例的以下方法:
                 * show(FragmentManager manager, String tag)
                 * show(FragmentTransaction transaction, String tag)
                 * 
                 * string参数可唯一识别存放在FragmentManager队列中的DialogFragment。
                 */
                dialog.show(fm, DIALOG_DATE);
            }
        });

传递数据给目标fragment

/**
     * 处理同一activity托管的两个fragment间的数据返回时,可借用Fragment.onActivityResult(...)方法。
     * 因此,直接调用目标fragment的Fragment.onActivityResult(...)方法,即可实现数据的回传。
     * 
     */
    private void sendResult(int resultCode) {
        if (getTargetFragment() == null)
            return;

        Intent intent = new Intent();
        intent.putExtra(EXTRA_DATE, mDate);

        getTargetFragment().onActivityResult(getTargetRequestCode(),
                resultCode, intent);
    }

更为灵活的DialogFragment视图展现

手机的屏幕非常有限。因此,通常需要使用一个activity托管全屏的fragment界面,以显示用户输入要求。该子activity会由父activity的fragment以调用startActivityForResult(…)方法启动。子activity销毁后,父activity会收到onActivityResult(…)方法的调用请求,并将之转发给启动子activity的fragment。

平板设备屏幕比较大。因此,以弹出对话框的方式显示信息和接受用户输入通常会更好。这种情况下,应该设置目标fragment并调用对话框fragment的show(…)方法。对话框被取消后,对话框fragment会调用目标fragment的onActivityResult(…)方法。

代码地址

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值