fragment间的数据传递

今天我将要讲的是fragment间的数据是如何进行传递的。这里我将举个简单的例子。

首先要有个MainActivity,它托管了MainFragment,而MainFragment又托管了DatePickerFragment。其间用到了简单的模型Crime,它只有Date类型的mDate一个属性。例子中的关注点是日期怎么在MainFragment和DatePickerFragment间传递的。

1.调整布局

strings.xml添加字符串资源

<resources>
    <string name="app_name">mytest</string>
    <string name="date_picker_title">Date of crime:</string> <!--添加这一行-->
</resources>

activity_main.xml添加FrameLayout布局

<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/fragment_container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.mytest.MainActivity">
</FrameLayout>

fragment_main.xml中添加button组件

<Button
        android:id="@+id/crime_data"
        android:text="初始时间"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

dialog_date.xml添加DatePicker组件

<DatePicker
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/dialog_date_picker"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:calendarViewShown="false">

</DatePicker>
2.Crime.java
public class Crime {
    private Date mDate;
    public Crime() {
        mDate=new Date();
    }
    public Date getDate() {
        return mDate;
    }
    public void setDate(Date date) {
        mDate = date;
    }
}
3. MainFragment.java

继承Fragment,在onCreateView方法中创建并配置fragment视图,其间设置按钮的监听事件,点击后,调用DatePickerFragment的静态函数newInstance,将数据保存在argument bundle中,并同时设置DatePickerFragment的目标fragment是MainFragment。最后设置对于DatePicker对话框的响应。

package com.example.mytest;

import android.app.Activity;
import android.content.Intent;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;

import java.util.Date;

public class MainFragment extends Fragment {
    private Crime mCrime;
    private Button mDateButton;

    private  static  final String DIALOG_DATE="DialogDate";
    private  static  final int REQUEST_DATE=0;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mCrime=new Crime();
    }
    //创建和配置fragment视图
    @Override
    public View onCreateView(LayoutInflater inflater,ViewGroup container,
                             Bundle savedInstanceState) {
        //加载布局
        View v=inflater.inflate(R.layout.fragment_main,container,false);
        //生成并使用组件
        mDateButton=(Button)v.findViewById(R.id.crime_data);
        mDateButton.setText(mCrime.getDate().toString());
        //mDateButton.setEnabled(false);
        mDateButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                FragmentManager manager=getFragmentManager();

                //newInstance替换构造方法
                //DatePickerFragment dialog=new DatePickerFragment();
                DatePickerFragment dialog=DatePickerFragment.newInstance(mCrime.getDate());

                //设置目标fragment
                dialog.setTargetFragment(MainFragment.this,REQUEST_DATE);

                dialog.show(manager,DIALOG_DATE); //显示DialogFragment
            }
        });
        return v;

    }

    //响应DatePicker对话框
    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        if(resultCode!= Activity.RESULT_OK){
            return;
        }
        if (requestCode==REQUEST_DATE){
            Date date=(Date) data.getSerializableExtra(DatePickerFragment.EXTRA_DATE);
            mCrime.setDate(date);
            mDateButton.setText(mCrime.getDate().toString());
        }
        super.onActivityResult(requestCode, resultCode, data);
    }
}
4.DatePickerFragment.java

直接获取保存在arguments中的数据,并将数据显示,最后设置目标fragment。

package com.example.mytest;

import android.app.Activity;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.support.v7.app.AlertDialog;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.DatePicker;

import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

public class DatePickerFragment extends DialogFragment{
    private static final String ARG_DATE="date";
    public static final String EXTRA_DATE= "com.example.mytest.date";

    private DatePicker mDatePicker;



    //便于被调用传递数据给DatePickerFragment
    //保存日期到argument bundle中,便于DatePickerFragment直接获取
    public static DatePickerFragment newInstance(Date date){

        Bundle args=new Bundle();
        args.putSerializable(ARG_DATE,date);

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

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        //获取Date对象并初始化DatePicker
        Date date=(Date)getArguments().getSerializable(ARG_DATE);

        Calendar calendar=Calendar.getInstance();
        calendar.setTime(date);
        int year=calendar.get(Calendar.YEAR);
        int month=calendar.get(Calendar.MONTH);
        int day=calendar.get(Calendar.DAY_OF_MONTH);

        //添加DatePicker
        View v=LayoutInflater.from(getActivity())
                .inflate(R.layout.dialog_date,null);

        mDatePicker=(DatePicker)v.findViewById(R.id.dialog_date_picker);
        mDatePicker.init(year,month,day,null);

        return new AlertDialog.Builder(getActivity())
                .setView(v)
                .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();
    }

    //回调目标fragment
    private void sendResult(int resultCode,Date date){
        if (getTargetFragment()==null){
            return;
        }
        Intent intent=new Intent();
        intent.putExtra(EXTRA_DATE,date);

        getTargetFragment().onActivityResult(getTargetRequestCode(),resultCode,intent);
    }
}
5.MainActivity.java

托管MainFragment,使界面呈现出来。

package com.example.mytest;

import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        FragmentManager fm=getSupportFragmentManager();
        Fragment fragment=fm.findFragmentById(R.id.fragment_container);

        if (fragment==null){
            fragment=new MainFragment();
            fm.beginTransaction()
                    .add(R.id.fragment_container,fragment)
                    .commit();
        }
    }
}
6.运行结果如下。

注意现在的时间点

1.png

点击按钮

2.png

更改一下时间点

3.png

按钮ok后时间改变了!

4.png

7.总结一下
1. 传递数据给DatePickerFragment
  • 要传递crime日期给DatePickerFragment,需将它保存在DatePickerFragment的argument bundle中。
    这样,DatePickerFragment就能直接获取它。
  • 创建和设置fragment argument通常是在newInstance()方法中完成的(代替fragment构造方法)。
2. 返回数据给MainFragment
  • 设置目标fragment。
    类似于activity间的关联,可将MainFragment设置成DatePickerFragment的目标fragment。这样,在MainFragment和DatePickerFragment被销毁并重建后,操作系统会重新关联它们。
    调用以下方法可建立这种关联:

public void setTargetFragment(Fragment fragment,int requestCode)

  • 传递数据给目标fragment
    建立MainFragment与DatePickerFragment之间的联系后,需要将数据回传给MainFragment。回传日期将作为extra附加给Intent。

转载于:https://www.cnblogs.com/mdx9626/p/7662754.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值