在上一篇学习安卓开发[1]-程序结构、Activity生命周期及页面通信中,学习了Activity的一些基础应用,基于这些知识,可以构建一些简单的APP了,但这还远远不够,本节会学习如何使用Activity托管Fragment的方式来进行开发

为什么需要Fragment

单纯使用Activity的局限

为什么需要Fragment呢,这要从Activity的局限说起。在前面使用Activity的过程中已经发现,Activity很容易被销毁重建,甚至是在设备旋转的时候也会被销毁,为了返回之前的状态需要保存各种界面相关的信息。

再来假设一种比较常见的场景,一个列表界面+明细界面构成的应用,如果用两个Activity来实现也可以,但如果用户在平板设备上运行应用,则最好能同时显示列表和明细记录,类似网易云、QQ那样在屏幕左侧约1/3的区域显示列表,右侧剩余的区域展示详细信息,这是使用两个Activity无法满足的;另外,查看能否在用户想查看下一条明细时不必回退、再点击进入明细界面,而是采用在屏幕横向滑动切换到下一条这样的快捷手势呢,这也是两个Activity无法满足的。

Fragment介绍

接下来该是Fragment隆重登场的时候了,可以说Fragment就是为了应对UI的灵活需求而生的,Fragment是在API 11中开始引入的,当时Google发布了第一台平板设备。

那么什么是Fragment呢,Fragment是一种控制器对象,可以在Activity的托管下进行用户界面的管理,受其管理的界面可以是整个屏幕区域,也可以是一小部分,Fragment(碎片)就是这个意思。

要让Activity能够托管Fragment,则需要activity视图预留fragment插入其中的位置。一个activity视图中可以插入过个fragment视图。Fragment本身没有在屏幕上显示视图的能力,所以它必须放置在Activity的视图层级中。

如何使用Fragment

代码实现
容器视图和Activity

在文件activity_fragment.xml中定义容器视图:

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

在Activity中定义了一个用于放置Fragment的FrameLayout,这个容器视图可以托管任意的Fragment。

对应Activity的代码在CrimeActivity.java为:

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_fragment); FragmentManager fm = getSupportFragmentManager();
Fragment fragment = fm.findFragmentById(R.id.fragment_container);
if (fragment == null) {
fragment = new CrimeFragment();
fm.beginTransaction()
.add(R.id.fragment_container, fragment)
.commit();
}
}
FragmentManager

这段代码的作用是:在资源ID为R.id.fragment_container的FrameLayout容器中,找到fragment,然后判断获取的fragment是否为空,如果为空则创建新的名为CrimeFragment的Fragment实例,将其添加到FragmentManager所维护的队列中,并在容器R.id.fragment_container中显示。

除了这种用代码将fragment交给Activity托管的方式,还可以在xml中直接将fragment签入activity,但为了能够动态地更换fragment,唯一能采用的便是前面采用的代码的方式。

在设备旋转或回收内存时,Android系统会销毁Activity,但FragmentManager会将fragment队列保存下来。Activity被重建时,新的FragmentManager会首先获取保存的队列(这就是使用了Fragment后,不会有像之前那样旋转就会设备导致状态丢失的现象的原因)。所以代码里会先判断fragment是否为null,只有为null的时候才会重新向队列中添加fragment。

Fragment的生命周期

Fragment的生命周期如下图所示:

可见Fragment的生命周期与Activity的生命周期非常类似,实际上Fragment的许多方法对应着activity的生命周期方法。

Fragment的onCreate方法:

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
}

Activity的onCreate方法:

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
}

两者的区别在于Fragment.OnCreate()是公共方法,而Activity.OnCreate()是受保护方法,Activity的生命周期方法由操作系统调用,而Fragment的生命周期方法则是由托管它的Activity调用的。

学习安卓开发[2] - 在Activity中托管Fragment的更多相关文章

  1. 学习安卓开发[3] - 使用RecyclerView显示列表

    在上一篇学习安卓开发[2] - 在Activity中托管Fragment中了解了使用Fragment的好处和方法,本次记录的是在进行列表展示时RecyclerView的使用. RecyclerView ...

  2. .Net程序员快速学习安卓开发-布局和点击事件的写法

    关注今日头条-做全栈攻城狮,学代码也要读书,爱全栈,更爱生活.提供程序员技术及生活指导干货. 本系列课程 致力于老手程序员可以快速入门学习安卓开发.系统全面的从一个.Net程序员的角度一步步学习总结安 ...

  3. 学习安卓开发[4] - 使用隐式Intent启动短信、联系人、相机应用

    在上一篇学习安卓开发[3] - 使用RecyclerView显示列表中了解了在进行列表展示时RecyclerView的使用,本次记录的是在应用中如何通过隐式Intent调用其它应用的功能,比如发短信. ...

  4. 程序员带你学习安卓开发系列-Android文件存储

    这是程序员带你学习安卓开发系列教程.本文章致力于面向对象程序员可以快速学习开发安卓技术. 上篇文章:.Net程序员快速学习安卓开发-布局和点击事件的写法 主要讲解了布局和点击事件的写法. 上篇文章补充 ...

  5. 程序员带你学习安卓开发,十天快速入-对比C#学习java语法

    关注今日头条-做全栈攻城狮,学代码也要读书,爱全栈,更爱生活.提供程序员技术及生活指导干货. 如果你真想学习,请评论学过的每篇文章,记录学习的痕迹. 请把所有教程文章中所提及的代码,最少敲写三遍,达到 ...

  6. 学习安卓开发[5] - HTTP、后台任务以及与UI线程的交互

    在上一篇学习安卓开发[4] - 使用隐式Intent启动短信.联系人.相机应用中了解了在调用其它应用的功能时隐式Intent的使用,本次基于一个图片浏览APP的开发,记录使用AsyncTask在后台执 ...

  7. 程序员带你学习安卓开发-XML文档的创建与解析

    这是程序员带你学习安卓开发系列教程.本文章致力于面向对象程序员可以快速学习开发安卓技术. 上篇文章:程序员带你学习安卓开发系列-Android文件存储 因知识连贯性推荐关注头条号:做全栈攻城狮.从头开 ...

  8. 学习安卓开发[1] - 程序结构、Activity生命周期及页面通信

    一.程序结构 Android原生应用采用了MVC的架构设计模式,因此可以将一个Android APP中的对象归为Model.View或Controller中的一种. 具体到某个实际的APP结构中,它一 ...

  9. 安卓开发笔记——深入Activity

    在上一篇文章<安卓开发笔记——重识Activity >中,我们了解了Activity生命周期的执行顺序和一些基本的数据保存操作,但如果只知道这些是对于我们的开发需求来说是远远不够的,今天我 ...

随机推荐

  1. Kali学习笔记41:SQL手工注入(3)

    前两篇文章都是基于目标系统允许union,order by语句 并且可以读取infomation_schema元数据库 如果遇到的是安全方面做得很好的应用,进行了权限限制,那么我们有什么办法呢? 猜测 ...

  2. Docker 搭建pxc集群 + haproxy + keepalived 高可用(二)

    上一节我们有了两个分片的pxc集群,这一节我们接着安装haproxy和keepalived的实现集群的高可用 一.先下载haproxy的镜像 [root@localhost ~]# docker pu ...

  3. VSCode与Deepin资源管理器冲突

    解决方式: xdg-mime default dde-file-manager.desktop inode/directory 此外,网上有较多推荐(在deepin 15.8版本上测试无效): gvf ...

  4. 如何优雅的利用Windows服务来部署ASP.NET Core程序

    上一篇文章中我给大家讲述了五种部署ASP.NET Core网站的方法,其中有一种方式是通过Windows服务来进行部署,这样既可以做到开启自启动,又不会因为iis的反向代理而损失部分性能.但是美中不足 ...

  5. Android--操作图片Exif信息

    前言 在Android系统中,图片文件在内存中以像素点的二维数组加载,存放像素信息,还会在开头加上一些额外的照片拍摄参数信息,这些信息就是Exif.Android2.0之后,媒体库加入了操作图片Exi ...

  6. 洛谷:P1036:选数

    题目描述 已知 nn 个整数 x1,x2,…,xnx1​,x2​,…,xn​ ,以及 11 个整数 kk ( k<nk<n ).从 nn 个整数中任选 kk 个整数相加,可分别得到一系列的 ...

  7. WebApi系列~对HttpClient的响应流进行解压

    回到目录 有时我们的请求头为ContentEncoding添加了gzip进行了压缩,而服务端返回数据时也会对它进行gzip压缩,如果在这种情况下,你直接头响应流会是乱码,而必须先进行压缩,大叔将这块的 ...

  8. RabbitMQ消息队列(十)-高可用集群部署实战

    前几章讲到RabbitMQ单主机模式的搭建和使用,我们在实际生产环境中出于对性能还有可用性的考虑会采用集群的模式来部署RabbitMQ. RabbitMQ集群基本概念 Rabbit模式大概分为以下三种 ...

  9. 【Java基础】【19异常&IO(File类)】

    19.01_异常(异常的概述和分类) A:异常的概述 异常就是Java程序在运行过程中出现的错误. B:异常的分类 通过API查看Throwable Error 服务器宕机,数据库崩溃等 Except ...

  10. pycharm安装破解go插件

    pycharm 2018以前版本安装go插件可以直接在plugins中搜索 go 插件,然后安装.若是2018以后的版本,go 变成了收费插件,plugins 搜不到.然后Google了一下,有人提供 ...