今天我将要讲的是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.运行结果如下。

注意现在的时间点

点击按钮

更改一下时间点

按钮ok后时间改变了!

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。

fragment间的数据传递的更多相关文章

  1. WinForm登陆:窗体间的数据传递

    1. 登陆逻辑 FrmMain 为主窗体(启动窗体) FrmLogin 为登陆窗体 在“主窗体”中使用ShowDialog()方法显示“登陆窗体”,并通过“登陆窗体”的DialogResult告知“主 ...

  2. C#不同窗体间通信,数据传递

    在一个项目中,很多时候都需要在窗体间进行数据传递和通信,最觉见的是父子窗体之间的数据传递,比如登录ID,各个窗体都需要知道.有很多文章都写了这方面的问题,提出很多优秀的方法,鄙人不才,搜了一些资料之后 ...

  3. iOS:控制器间的数据传递

    在iOS开发中遇到的控制器间的数据传递主要有两种情况:顺传递与逆传递.顺传递是指数据的传递方向和控制器的跳转方向相同(如图1):逆传递是指数据的传递方向和控制器的跳转方向相反(如图2).这里分别介绍这 ...

  4. 【转】Unity3d的单例及场景间的数据传递

    http://blog.csdn.net/zy19940906/article/details/47724387  单例是场景间切换时传递数据的最常见的方式之一,在unity中,很多方法被封装,有时候 ...

  5. hive、sqoop、MySQL间的数据传递

    hdfs到MySQL csv/txt文件到hdfs MySQL到hdfs  hive与hdfs的映射: drop table if exists emp;create table emp ( id i ...

  6. React Native移动开发实战-3-实现页面间的数据传递

    React Native使用props来实现页面间数据传递和通信.在React Native中,有两种方式可以存储和传递数据:props(属性)以及state(状态),其中: props通常是在父组件 ...

  7. vue组件间的数据传递

    父组件向子组件传递数据 在 Vue 中,可以使用 props 向子组件传递数据.   App.vue HelloWorld.vue 在子组件部分: 如果需要从父组件获取 logo 的值,就需要使用 p ...

  8. 零基础Android学习笔记-03 窗口间的数据传递

    1.通过全局变量来传递. 新建一个全局的类继承于Application package com.example.helloworld; import android.app.Application; ...

  9. ASP.NET-页面间的数据传递

    暑假期间做项目时遇到相关问题,总结如下,与大家分享 1.通过查询字符串传递 这种方式是将参数附加在网址的后面,传递数据简单,但容易暴露,一般用于传递一些简单的数据. 例如,在Default1.aspx ...

随机推荐

  1. Web端口复用正向后门研究实现与防御

    0×01背景 现在的很多远控/后门因为目前主流防火墙规则的限制,基本上都采用TCP/UDP反弹回连的通讯形式:但是在较高安全环境下,尤其负责web相关业务的环境,因为安防设备(防火墙,IDS,IPS等 ...

  2. Linux挂载新盘

    Linux 系统挂载数据盘 1.查看数据盘 使用“fdisk-l”命令查看 2. 对数据盘进行分区 执行“fdisk /dev/sdb”命令,对数据盘进行分区: 输入“n”,“p”“1”,两次回车,“ ...

  3. for in、for和EnumerateObjectsUsingBlock遍历的区别

    1.对于集合中对象数很多的情况下,for in 的遍历速度非常之快,但小规模的遍历并不明显(还没普通for循环快) 2. 如果在for in 循环里,对这个数组进行了修改的话,无论是增,删,修改数组元 ...

  4. javascript的继承方法

    一.构造函数继承 该方法最简单,使用call或者apply方法,将父对象的构造函数绑定到子对象上. function Parent(name){ this.name = name; this.colo ...

  5. Ext sqlserver C# 数据库备份还原代码,给大家参考下

      <%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<dynamic>" %& ...

  6. MySQL Study之--MySQL压力測试工具mysqlslap

    MySQL Study之--MySQL压力測试工具mysqlslap 一.Mysqlslap介绍     mysqlslap是MySQL5.1之后自带的benchmark基准測试工具,类似Apache ...

  7. 【图像处理】基于OpenCV底层实现的图片旋转

    image processing 系列 [图像处理]直方图匹配 [图像处理]高斯滤波.中值滤波.均值滤波 图片旋转,本质上是对旋转后的图片中每一个像素点计算在原图的位置.然后照搬过来就好. (多说一句 ...

  8. iOS 保存视频AVAssetWriter

    错误的CMTime导致保存的视频无效,比如: frameTime CMTime 1122 600ths of a second value CMTimeValue 1122timescale CMTi ...

  9. iOS 特定图片的button的旋转动画

    近期做的东西中,要为一个有特定图片的button加入旋转动画,Demo代码例如以下: #import "ViewController.h" @interface ViewContr ...

  10. luogu 1901 发射站

    题目大意: 一个数列,它左边第一个比它高的人和右边第一个比它高的人要加上它的权值 思路: 单调栈维护一个单调递减的栈 正反各维护一遍 #include<iostream> #include ...