Fragment进阶 - 基本用法

Fragment API文档
(需要翻墙)

本文内容

  • Fragment生命周期
  • Fragment创建步骤
  • Fragment静态加载
  • Fragment动态加载

1. Fragment生命周期

(下图为Steve Pomeroy制作的完整的Fragment生命周期图

image.png

注意点:

  1. Fragment以XML的方式静态加载时,最先会调用onInflate的方法(调用时机:Fragment所关联的Activity在执行setContentView时)。

  2. onInflate有两个重载的方法:

    • onInflate(Context context, AttributeSet attrs, Bundle savedInstanceState)(推荐使用)

    • onInflate(Activity activity, AttributeSet attrs, Bundle savedInstanceState)(已废弃,不推荐被外部类调用)

  3. onAttach也有两个重载的方法:

    • onAttach(Context context)(推荐使用)

    • onAttach(Activity activity)(已废弃,不推荐被外部类调用)


2. Fragment的创建步骤(最简单的方式)

1.创建XML视图(供Fragment进行管理)

fragment_xml.png

2.创建Fragment

fragment.png

通过这两步我们的Fragment已经创建完毕了,接下来就是使用了。


3. Fragment静态加载

静态加载是指以XML的方式进行加载。(Activity和对应布局,如下图所示)

main.png

在fragment标签中需要添加name属性来指定你想添加的Fragment。

接下来我们跑一下程序,界面就加载出来了。

app.png

接下来,给各位踩一下“静态加载Fragment”可能出现的坑。

我们的fragment在xml中是这样写的,运行没有问题。

<fragment
    android:id="@+id/content_fragment"
    android:name="com.sina.example.fragmentdemo.fragment.ContentFragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

但如果android:id这个属性忘记写的话就要遭殃了(事例如下)...

<fragment
    android:name="com.sina.example.fragmentdemo.fragment.ContentFragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

我们去掉android:id属性跑下程序,结果程序崩了...,检查崩溃日志后得到了两条关键日志信息:

......
Caused by: android.view.InflateException: Binary XML file line #6: Error inflating class fragment
......
Caused by: java.lang.IllegalArgumentException: Binary XML file line #6: Must specify unique android:id, android:tag, or have a parent with an id for com.sina.example.fragmentdemo.fragment.ContentFragment

第1条信息:告诉我们在Fragment填充布局的时候出错了。

第2条信息:告诉我们解决这个问题的办法:必须指定android:id或android:tag或给我们的fragment的父容器一个id(解决办法如下图所示)。

solve_error.png

紧接着,我们用Hierarchy Viewer分析一下图层,说明一种现象。

(1). 打开视图后,我们最先看到的是视图树的根View - DecorView(PhoneWindow的内部类)

viewer.png

(2). 顺着视图树向后看,我们看到一个id/content的视图容器.

viewer2.png

我们在Activity中setContentView就是向这个视图容器(android.R.id.content)中添加布局的。
下方分支是ActionBar的相关布局,如果将标题栏去掉,你会发现下方的分支消失了。

(3). 最后,可以看到我们自己写的布局文件

viewer3.png
  • id/rl_main:是我们赋给Acitivity布局文件根布局的id值。

  • id/content_fragment:是我们赋给fragment的id值(但视图中却变成了RelativeLayout)

  • AppCompatImageView:我们的ImageView,未赋Id值。

细心观察,我们会发现Fragment的id值赋给的了它所管理视图的最外层布局(RelativeLayout)。经过测试,发现不止id值,其他属性也赋值给了最外层布局(赋值是指对RelativeLayout没有的属性进行添加,已有的属性进行刷新)。

结论:静态加载Fragment时,Fragment在XML设置的属性将赋值给它所管理视图的最外层布局。

最后,看下如何在Activity中找到我们的Fragment。

FragmentManager里有提供了“两种方法”查找我们的Fragment:

  • findFragmentById(@IdRes int id) : 通过id查找Fragment。(查找过程:第一次查找会从FragmentManager所管理的所有Fragment里查找,如果找不到,则会从关联过这个id的回退栈的所有Fragment里查找。如过找到则返回这个指定id的Fragment,否则返回null。)

  • findFragmentByTag(String tag):通过Tag查找Fragment。(查找过程:类比id的查找过程)

看下上一步,我们Fragment的id值已经赋给了它所管理视图的最外层布局了,我们试下还能不能找到这个Fragment。

fragment.png
  • 我们通过查找id的方式找到了我们的Fragment(ContentFragment)

  • 同一个id(R.id.content_fragment)以不同的方式查找得到了两个不同的对象

    • findViewById的方式我们得到的是Fragment的视图容器RelativeLayout。
    • findFragmentById的方式我们得到的是Fragment的实例ContentFragment。

4. Fragment动态加载

activity.png

步骤:

  1. 在Activity的XML布局文件中添加一个FrameLayout视图容器(用于存放Fragment被添加后Fragment所管理的视图)。
  2. 在Activity中调用一个链式方法完成Fragment的动态添加。
    • getSupportFragmentManager() : 获取Fragment管理器(需要support.v4包)
    • beginTransaction() : 使Fragment管理器开启一个事务
    • add(R.id.fl-main, new ContentFragment(), null) : 在事务中进行一个添加操作,将目标Fragment添加到我们在步骤1中提供好的视图容器(R.id.fl_main)中 ,该Fragment的tag设为null。
    • commit() : 提交事务到主线程执行添加操作。

PS:使用getSupportFragmentManager() 需要导入support.v4包,用来对Android3.0以下的版本进行兼容,不需要向下兼容可以考虑用 getFragmentManager()

最后,跑一下程序,我们的界面就显示出来了。

app.png

接着,我们用Hierarchy Viewer查看一下图层,看下是不是我们所想象的。

viewer4.png

果然,Fragment中的布局完全装进了fl-main这个视图容器里,说明实例也已经被添加了。

这里仅仅是介绍Fragment最简单的动态加载,后面小编会在FragmentTransaction里进行更详细的介绍。

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

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,501评论 25 707
  • 在各种Android项目中,我们不可避免要使用到Fragment,但很多地方其实我们只是习惯性或copy代码来使用...
    HolenZhou阅读 2,072评论 1 15
  • Fragment 描述:   翻译可以译为:碎片、片段,Android 3.0开始引入fragments 的概念;...
    Lost_Robot阅读 1,682评论 0 11
  • 从张琦屋里出来特意往311走,还真就看见汪书琪,对视了一眼。我觉得是我赢了。这小姑娘心乱了。 回泡崖和张金宝打篮球...
    自由的adam爱生活阅读 433评论 0 0
  • 如果有一样东西你必须学,他不可或缺,你学不会就无法继续生活……那这样东西不要任何人逼你,不用任何人向你灌输“他太有...
    陈东Growth阅读 299评论 0 0