学习笔记| AS入门(六) 碎片Fragment

安卓自3.0开始引入Fragment的概念,主要是为了能在不同分辩率屏幕上进行更为动态和灵活的UI设计,让程序更加合理和充分利用大屏幕空间。本篇将学习Fragment以下几个知识点:

  • Fragment概要
  • Fragment生命周期
  • 加载Fragment方法
    • 静态加载
    • 动态加载
  • Fragment与Activity之间通信

1.Fragment概要

学习Fragment的时候可以联系之前学习过的Activity,因为它们有很多相似点:都可包含布局,有自己的生命周期,Fragment可看似迷你活动。正如Fragment的名字--碎片,它的出现是为了解决Android碎片化 ,它可作为Activity界面的组成部分,可在Activity运行中实现动态地加入、移除和交换。一个Activity中可同时出现多个Fragment,一个Fragment也可在多个Activity中使用。活动和碎片像极了夫妻, 虽然紧密联系但是又有独立空间,在一起让彼此变得更好。

下面这个非常经典的例子更直观地说明了Fragment作用:

2.Fragment生命周期

先来看官方文档提供的有关Fragment生命周期的图片。

是不是能发现Fragment和Activity的生命周期太相似了,现在只需要再介绍几个Activity中没讲过的新方法:

onAttach():当Fragment和Activity建立关联时调用
onCreateView():当Fragment创建视图时调用
onActivityCreated():当与Fragment相关联的Activity完成onCreate()之后调用
onDestroyView():在Fragment中的布局被移除时调用
onDetach():当Fragment和Activity解除关联时调用

在上图中画了几条线,可以看到Fragment周期中的状态几乎都是成对出现的,所以不难理解下图几种变化下Fragment生命周期方法的调用顺序了。

加载到Activity中的Fragment在各种变化下方法的调用顺序更值得注意。需要提一句的是,Activity的FragmentManager负责调用队列中Fragment的生命周期方法,只要Fragment的状态与Activity的状态保持了同步,托管Activity的FragmentManager便会继续调用其他生命周期方法以继续保持Fragment与Activity的状态一致。

Fragment生命周期与Activity生命周期的一个关键区别就在于,Fragment的生命周期方法是由托管Activity而不是操作系统调用的。Activity中生命周期方法都是protected,而Fragment都是public,也能印证了这一点,因为Activity需要调用Fragment那些方法并管理它。

3.加载Fragment方法

现在就来学习如何在Activity中加载Fragment。

(1)静态加载:在托管Activity的layout文件中声明Fragment

静态加载Fragment大致过程如图,分成四步:

下面通过一个简单的例子感受Fragment静态加载到Activity的过程。

第一步:新建frag_layout.xml,为Fragment指定一个布局,这里简单的放一个TextView和一个Button。

第二步:新建一个MyFragment类并继承Fragment,这里引用android.app包下的就可以,另一个包下主要用于兼容低版本的安卓系统。然后重写onCreateView()方法,这个方法里通过LayoutInflater的inflate()方法将刚刚定义的frag_layout布局加载进来并得到一个View,再return这个View。

第三步:新建mian.xml,作为Activity的布局,使用< fragment>标签添加碎片,并且一定要有android:name属性且值为被加载的Fragment类的包名.类名完整形式。

第四步:在MainActivity中加载main布局。现在MyFragment就完成了静态加载到MainActivity中,这时碎片里的控件自然也是活动的一个部分,可直接在活动中获取到Button的实例,来注册点击事件了。

运行一下看看能不能达到效果:

(2)动态加载:在托管Activity通过代码动态添加

动态加载的代码也非常简单,直接看例子。修改main.xml,将整个< fragment>删掉。但还保留一个LinerLayout的空间并且还给了Id,为何这样做?马上揭秘。

接下来在MainActivity中添加几行代码:

可将整个过程大致分为三个步骤:

第一步,先用getFragmentManager()方法获取一个FragmentManager对象,再通过它的beginTransaction()获取一个FragmentTransaction的实例。

第二步,用beginTransaction.add()方法将MyFragemnt实例添加到main布局里LinearLayout里,终于知道之前铺垫的Id是怎么回事了。一定要注意,add()方法里的第一个参数是容器视图资源Id,而不是layout。容器视图资源Id有两个作用:告知FragmentManager,碎片视图应该出现在活动视图的什么地方;它也是FragmentManager队列中碎片的唯一标识符。而静态加载时碎片的唯一标识符正是在活动布局里< fragment>下的id。

第三步:调用beginTransaction.commit()提交。另外,如果允许用户通过按下返回按键返回到前一个Fragment状态,在调用commit()之前先调用addToBackStack(true)方法。

这里注意到动态加载进来的Fragment里的控件并不能直接在活动中findViewById得到,那么如何实现点击效果呢,学完下一个知识点就有办法了。

4.Fragment与Activity之间通信

在活动中可以通过调用FragmentManagerfindFragmentById()方法来得到相应碎片的实例,继而可以调用碎片里的方法。以上面demo举例,如果想得到静态加载碎片的实例,可在MainActivity添加代码如下:

MyFragment myFragment = (MyFragment)getFragmentManager(). findFragmentById(R.id.fragment);

如果想得到动态加载碎片的实例,代码如下:

MyFragment myFragment = (MyFragment)fragmentManager(). findFragmentById(R.id.layout);

在碎片中也可以通过调用getActivity()方法来得到和当前碎片相关联的活动实例,这样调用活动里的方法就变得轻而易举了。比如想在MyFragment得到MainActivity的实例:

MainActivity activity=(MainActivity)getActivity();

于是碎片和活动可以很方便地进行通信了。再想一想碎片和碎片之间如何进行通信?先在一个碎片中可以得到与它相关联的活动,然后再通过这个活动去获取另外一个碎片的实例,这样实现了不同碎片之间的通信了。

现在你有没有想到解决之前那个问题的办法呢?可以这样做,修改MyFragment,代码如下图所示:

现在按钮点击就又有响应了!其实在实际开发中,如果某一板块每次用到都需要相同的功能,就完全可以在碎片中实现需求,而不必在活动中重复代码,这样可以提高代码的复用性。

> 下一篇预告:数据存储篇

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

推荐阅读更多精彩内容