Android编程权威指南(第二版)学习笔记(十二)—— 第12章 对话框

本章主要介绍了如何使用内嵌在 fragment 中的对话框,以及 fragment 之间如何传递数据

GitHub 地址:
完成第12章

1. 使用 DialogFragment

1.1 AppCompat 兼容库

Google 推出 AppCompat 兼容库是为了让所有Android用户都能体验到新特性。AppCompat兼容库能通过支持库的方式将部分最新系统的特色功能移植到Android旧版本系统中。

应该在 Porject Structure 中添加 appcompat-v7 的依赖。

1.2 创建 DialogFragment

建议将 AlertDialog 封装在 DialogFragment (Fragment的子类)实例中使用。当然,不使用DialogFragment 也可显示 AlertDialog 视图,但不推荐这样做。使用 FragmentManager 管理对话框,可以更灵活地显示对话框。

如果旋转设备,单独使用的 AlertDialog 会消失,而封装在 fragment 中的 AlertDialog 则不会有此问题(旋转后,对话框会被重建恢复)。

  • 首先需要一个针对 dialog 的布局文件,如 DatePicker 作为根元素的 Dialog 用于选择日期。
<?xml version="1.0" encoding="utf-8"?>
<DatePicker xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/dialog_date_date_picker"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:calendarViewShown="false">
    <!--旧版系统会使用 calenderViewShown 属性-->

</DatePicker>
  • 然后新建一个父类是 DialogFragment 的类 DatePickerFragment,重写其中的 onCreateDialog 方法,返回一个AlertDialog
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
    // 使用 LayoutInflater 引用布局文件创建用于显示 Dialog 的 View
    View v = LayoutInflater.from(getActivity())
                .inflate(R.layout.dialog_date, null);
                
    return new AlertDialog.Builder(getActivity())
        .setView(v) // 设置视图
        .setTitle(R.string.date_picker_title) //设置标题
        // 设置 OK 按钮,OnClickListener 暂时留空
        .setPositiveButton(android.R.string.ok, null)
        // 使用 Builder 的 create() 方法创建 Dialog 并返回
        .create(); 
}

在使用 DialogFragment 时,使用成员方法 show 来显示 dialog:

// 在 Fragment 中为 DatePickerFragment 添加一个 Tag
private static final String DIALOG_DATE = "DialogDate";
……
// 在 Fragment 内部获取 FragmentManager
FragmentManager manager = getFragmentManager(); 
DatePickerFragment dialog = new DatePickerFragment();
// 显示对话框
dialog.show(manager, DIALOG_DATE);

2. fragment 之间的数据传递

我们之前实现了 activity 之间以及基于 fragment 的 activity 之间的数据传递。现在需实现同一 activity 托管的两个 fragment 之间的数据传递。


一个 activity 托管的不同 fragment 之间数据的传递

2.1 将数据传递到对话框

显然,要达到目的,只需要在 DatePickerFragment 中建立获取实例的 newInstance 方法,其中需要的参数是传递的信息即可,示例如下

// DatePickerFragment.java

public static DatePickerFragment newInstance(Date date) {
    // 新建一个 Bundle 对象用于存放数据
    Bundle args = new Bundle();
    args.putSerializable(ARG_DATE, date);
    DatePickerFragment fragment = new DatePickerFragment();
    // 使用 fragment arguments 来传递参数
    fragment.setArguments(args);
    return fragment;
}

记得把使用 DatePickerFragment 的构造方法的地方改成 newInstance 方法获取实例。

在获得数据之后,要先将 DatePicker 初始化为原本的日期,首先用 Fragment 的 getArguments().getSeriallizable(String key) 方法获取数据,然后用 Calendar 对象取出 date 中的年月日,最后使用 DatePicker 类的 init(int year, int month, int dayOfMonth, OnDateChangedListener listener) 方法 初始化默认日期

2.2 从对话框回传数据

2.2.1 设置目标 fragment

类似于 activity 间的关联,可将 CrimeFragment 设置成 DatePickerFragment 的目标 fragment。 即使是在 CrimeFragment 和 DatePickerFragment 被销毁和重建后,操作系统也会重新关联它们。调用以下 Fragment 方法可建立这种关联:

public void setTargetFragment(Fragment fragment, int requestCode)

该方法有两个参数:目标 fragment 以及请求代码。需要时,目标 fragment 使用请求代码确认是哪个 fragment 在回传数据。

目标 fragment 和请求代码由 FragmentManager 负责跟踪管理,我们可调用设置目标的 fragment 的 getTargetFragment()getTargetRequestCode() 方法获取它们。

2.2.2 传递数据给目标 Fragment

处理由同一 activity 托管的两个 fragment 间的数据返回时,可借用Fragment.onActivityResult(...)方法。因此,直接调用目标 fragment 的Fragment.onActivityResult(...)方法,,就能实现数据的回传。该方法恰好有我们需要的如下信息:

  • 请求代码:与传入setTargetFragment(...)方法相匹配,告诉目标 fragment 返回结果来 自哪里。
  • 结果代码:决定下一步该采取什么行动。
  • Intent:包含 extra 数据。

所以从 CrimeFragment 中显示 DatePickerFragment,用户选择日期以后,想要回传信息,可以写一个 sendResult 方法,该方法如下:

// DatePickerFragment.java

public static final String EXTRA_DATE =
    "com.kniost.criminalintent.date";
 ……                
private void sendResult(int resultCode, Date date) {
    // 防止出错
    if (getTargetFragment() == null) {
        return; 
    }
    Intent intent = new Intent();
    // 放置数据到 Intent 中
    intent.putExtra(EXTRA_DATE, date);
    // 获取目标 fragment,调用其 onActivityResult 方法,其中 RequestCode 是用 getTargetRequestCode 方法获取的,resultCode 是传入参数,intent 包含了数据
    getTargetFragment()
        .onActivityResult(getTargetRequestCode(), resultCode, intent);
}

在 CrimeFragment 中则应该重写 onActivityResult 方法:

// CrimeFragment.java

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    // 如果一切正常,调用 sendResult 的方法时传入的参数应该就是 Activity.RESULT_OK,所以不会直接 return
    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());
    }
}

3. 挑战练习

//待完成


GitHub Page: kniost.github.io
简书:http://www.jianshu.com/u/723da691aa42

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,189评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,577评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,857评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,703评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,705评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,620评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,995评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,656评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,898评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,639评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,720评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,395评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,982评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,953评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,195评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,907评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,472评论 2 342

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,421评论 25 707
  • Jedis是java语言实现的Redis客户端驱动。Data Redis的封装并不太必要,因为Jedis已足够简单...
    zhanglbjames阅读 1,572评论 1 1
  • 晕车复晕车, 日日都没喝。 长啸且徐行, 我行亦我歌。
    迁于乔木阅读 153评论 0 0
  • 如果可以拥抱 那就 别只顾着握手寒暄 因为 黑夜很长 冬天很冷 如果可以多给祝福 那就 请少给建议 因为 奔跑的路...
    老草阅读 174评论 1 1
  • 对于世界. 可能我只是一个人! 但对于某个人.曾经的我是他的整个世界!
    Ring_my_bell阅读 82评论 0 1