我要做 Android 之Fragment

简介: Q:谈一谈Fragment的生命周期?一:首先说说时间节点:Fragment 是在 Android3.0+ 以后,Android 新增了 Fragments,在没有 Fragment 之前。

Q:谈一谈Fragment的生命周期?

一:首先说说时间节点:Fragment 是在 Android3.0+ 以后,Android 新增了 Fragments,在没有 Fragment 之前。一个屏幕只能放一个 Activity。这是一个起源时间大家什么时候引入。(ps:为了屏幕适配的原因翻译为碎片)

Fragment 概要

学习 Fragment 的时候可以联系之前学习过的 Activity ,因为它们有很多相似点:都可包含布局,有自己的生命周期,Fragment 可看似迷你活动。正如 Fragment 的名字--碎片,它的出现是为了解决 Android 碎片化 ,它可作为Activity 界面的组成部分,可在 Activity 运行中实现动态地加入、移除和交换。一个 Activity 中可同时出现多个Fragment,一个 Fragment 也可在多个 Activity 中使用。

Activity 代表了一个屏幕的主体,而 Fragment 可以作为 Activity 的一个组成元素。
一个 Activity 可以有若干个(0或n)Fragment 构成。你可以把 Fragment 想象成 Activity 中的一个控件,只不过相对于一般控件,Fragment 与 Activity 联系更为紧密,随着 Activity 的生命周期变化,Fragment 也随之相应不同的生命周期函数。
Fragment 从功能上讲相当于一个子活动(Activity),它可以让多个活动放到同一个屏幕上,也就是对用户界面和功能的重用,因为对于大屏设备来说,纯粹的 Activity 有些力不从心。


img_5c69ea23598c0e612692fccdef1748ce.png
fr01.png

2.Fragment生命周期

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


img_f8e1641b546e399803fcf23bf3acd940.png
fr02.png

由上图可以发现 Fragment 和 Activity 的生命周期很相似,可以说大致周期的情况是基本相同的。现在只需要在介绍几个 Activity 中没有讲过的新方法。

onAttach(): 当 Fragment 和 Activity 建立关联的时候调用

onCreateView() : 当 Fragment 创建视图的时候调用

onActivityCreated(): 当与 Fragment 相关联的 Activity 完成 onCreate() 之后调用

onDestoryView(): 当 Fragment 中的布局被移除的时候调用

onDetach(): 当 Fragment 和 Activity 解除关联的时候调用

所以根据 Activity 的周期方法我们可以大致判断周期画面

(1)打开页面的时候

onCreate -> onCreateView -> onActivityCreated -> onStart -> onResume 

(2)按下主屏幕键

onPause -> onStop

(3)重新打开界面

onStart -> onResume

(4)按后退键

onPause -> onStop -> onDestroyView -> onDestroy -> onDetach

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

注意注意注意

当 Activity 加入 Fragment

(1)打开界面

Fragment onCreate() -> Fragment onCreateView() -> Activity onCreate() -> Fragment onActivityCreated() -> Activity onStart() -> Fragment onStart() -> Activity onResume() -> Fragment onResume()

(2)按下主屏幕键

Fragment onPause() -> Activity onPause() -> Fragment onStop() -> Activity onStop()

(3)重新打开界面

Activity onRestart() -> onActivity start() -> Fragment onStart() -> Activity onResume() -> Fragment onResume()

(4)按后退键退出

Fragment onPause() -> Activity onPause() -> Fragment onStop() -> Activity onStop() -> Fragment onDestroyView() -> Fragment onDestroy() -> Fragment onDetach() -> Activity onDestroy()

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

三:加载 Fragment 方法

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

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

静态加载 Fragment 大致过程分为四步:

img_a7b0ae93f7400c65b3f6494b451ba33b.png
fr03.png

我会在下方给出一个 demo 让大家感受以下 (ps:一定要自己动手写一遍,感受和看的真的不一样,会给你带来肌肉记忆。)

第一:新建一个 frag_layout.xml 布局,这是 Fragment 的布局,这里就只有一个显示 TextView 和 Button。

img_6c525ed7457aef5d2b60290fa52077b7.png
fr04.png

第二:新建一个 MyFragment 类并继承 Fragment,这里引用 v4 下的包,具有兼容性。顺便提一下,正常我们引入包的时候都用 v4 或者 v7 下的包,这里的包都是向下兼容,否则可能会出现意想不到的问题。我们在这里重写 onCreateView()方法,这个方法里通过 LayoutInflate 的 inflate() 方法将刚定义的 frag_layout 布局加载进来并得到一个 View,在 return 这个 view 就 OK。


img_adaf098d52b77dcf46c7afb3df66fd76.png
fr07.png

第三:在 main_xml 布局中修改,使用 < fragment > 标签来添加碎片,并且切记切记要加上 android:name 属性。之后会有自动提示,加载的完整形式是 包名.类名


img_e6b76a2d12669087bbe31d939d9027b6.png
fr08.png

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

img_ee4ca9888e9a771482479bd0cf5a7add.png
fr09.png

看下运行结果:

img_ab0ef7cb1cb02c292bb9119b4185736c.png
fr06.png

second:动态加载:在托管 Activity 通过代码动态添加

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


img_0042049e397681463c61744042b8a298.png
fr11.png

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


img_118765816e30b3be657610c33c0033a3.png
fr10.png

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

第一步,先用 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得到,那么如何实现点击效果呢,学完下一个知识点就有办法了。

Fragment 与 Activity 之间的通信

在活动中可以通过调用 FragmentManager 的 findFragmentById() 方法来得到相应碎片的实例,继而可以调用碎片里的方法。以上面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();

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


img_c3f3534b8e98d2f12bae02e3f176f12f.png
fr12.png

只要这样我们就有能够正常的使用了。

就我个人而言,正常 APP 中都是一个 Activity 带几个 Fragment,所以这时候我们需要通过适配器来实现。实现之后每一个 Fragment 对应的操作依然在各自的 Fragment 中来实现。而不是在 Activity 中。

目录
相关文章
|
XML Android开发 数据格式
Android -- Fragment动态注册
Android -- Fragment动态注册
84 0
|
25天前
|
缓存 前端开发 Android开发
Android实战之如何截取Activity或者Fragment的内容?
本文首发于公众号“AntDream”,介绍了如何在Android中截取Activity或Fragment的屏幕内容并保存为图片。包括截取整个Activity、特定控件或区域的方法,以及处理包含RecyclerView的复杂情况。
18 3
|
6月前
|
XML 存储 Android开发
Android技能树 — Fragment总体小结,2024年最新腾讯面试gm
Android技能树 — Fragment总体小结,2024年最新腾讯面试gm
|
6月前
|
XML Android开发 数据格式
Fragment的使用,零基础入门android逆向视频课程
Fragment的使用,零基础入门android逆向视频课程
|
6月前
|
Android开发
Android基础知识:什么是Fragment?与Activity的区别是什么?
Android基础知识:什么是Fragment?与Activity的区别是什么?
1195 54
|
6月前
|
XML Java Android开发
Android Studio App开发之碎片Fragment的讲解及实战(附源码 包括静态和动态注册)
Android Studio App开发之碎片Fragment的讲解及实战(附源码 包括静态和动态注册)
362 1
|
6月前
|
Android开发 Kotlin
android开发,使用kotlin学习Fragment
android开发,使用kotlin学习Fragment
141 0
|
Android开发 容器
Android上机实验-6 Fragment的使用
Android上机实验-6 Fragment的使用
114 1
|
Android开发
Android ViewModel+LiveData实现Fragment间通信详解
Android ViewModel+LiveData实现Fragment间通信详解
189 0
|
Android开发
Android 中Activity和Fragment生命周期的具体变化详解
Android 中Activity和Fragment生命周期的具体变化详解
194 0