Site Overlay

Android Fragmnet详解

授予每个自然月内发布4篇或4篇以上原创或翻译IT博文的用户。不积跬步无以至千里,不积小流无以成江海,程序人生的精彩需要坚持不懈地积累!

授予每个自然周发布1篇到3篇原创IT博文的用户。本勋章将于次周周三上午根据用户上周的博文发布情况由系统自动颁发。

android studio将项目中module变成library引用依赖

u013791665:我在概览屏幕中滑动清除子任务,为什么主任务中的activity会被系统强杀

FragmentFragment用法Google文档模块化android基础

版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。

。您可以将多个Fragment组合在一个 Activity 中来构建多窗格 UI,以及在多个 Activity 中重复使用某个

视为Activity 的模块化组成部分,它具有自己的生命周期,能接收自己的输入事件,并且您可以在 Activity 运行时添加或删除

(有点像您可以在不同 Activity 中重复使用的“子Activity”)。

Fragment必须始终嵌入在 Activity 中,其生命周期直接受宿主 Activity 生命周期的影响。例如,当 Activity 暂停时,其中的所有Fragment也会暂停;当 Activity 被销毁时,所有Fragment也会被销毁。 不过,当 Activity 正在运行(处于已恢复生命周期状态)时,您可以独立操纵每个Fragment,如添加或移除它们。当您执行此类Fragment事务时,您也可以将其添加到由 Activity 管理的返回栈—Activity 中的每个返回栈条目都是一条已发生Fragment事务的记录。 返回栈让用户可以通过按“返回”按钮撤消Fragment事务(后退)。

当您将Fragment作为 Activity 布局的一部分添加时,它存在于 Activity 视图层次结构的某个 ViewGroup 内部,并且Fragment会定义其自己的视图布局。您可以通过在 Activity 的布局文件中声明Fragment,将其作为 fragment元素插入您的 Activity 布局中,或者通过将其添加到某个现有 ViewGroup,利用应用代码进行插入。不过,Fragment并非必须成为 Activity 布局的一部分;您还可以将没有自己 UI 的Fragment用作 Activity 的不可见工作线程。

本文描述如何在开发您的应用时使用Fragment,包括将Fragment添加到 Activity 返回栈时如何保持其状态、如何与 Activity 及 Activity 中的其他Fragment共享事件、如何为 Activity 的操作栏发挥作用等等。设计原理Android 在 Android 3.0(API 11 级)中引入了Fragment,主要是为了给大屏幕(如平板电脑)上更加动态和灵活的 UI 设计提供支持。由于平板电脑的屏幕比手机屏幕大得多,因此可用于组合和交换 UI 组件的空间更大。利用片段实现此类设计时,您无需管理对视图层次结构的复杂更改。通过将 Activity 布局分成Fragment,您可以在运行时修改 Activity 的外观,并在由 Activity 管理的返回栈中保留这些更改。

例如,新闻应用可以使用一个Fragment在左侧显示文章列表,使用另一个Fragment在右侧显示文章—两个片段并排显示在一个 Activity 中,每个Fragment都具有自己的一套生命周期回调方法,并各自处理自己的用户输入事件。 因此,用户不需要使用一个 Activity 来选择文章,然后使用另一个 Activity 来阅读文章,而是可以在同一个 Activity 内选择文章并进行阅读,如图 1 中的平板电脑布局所示。

您应该将每个Fragment都设计为可重复使用的模块化 Activity 组件。也就是说,由于每个Fragment都会通过各自的生命周期回调来定义其自己的布局和行为,您可以将一个Fragment加入多个Activity,因此,您应该采用可复用式设计,避免直接从某个Fragment直接操纵另一个Fragment。这特别重要,因为模块化Fragment让您可以通过更改Fragment的组合方式来适应不同的屏幕尺寸。在设计可同时支持平板电脑和手机的应用时,您可以在不同的布局配置中重复使用您的Fragment,以根据可用的屏幕空间优化用户体验。例如,在手机上,如果不能在同一Activity 内储存多个Fragment,可能必须利用单独Fragment来实现单窗格 UI。

图 1. 有关由Fragment定义的两个 UI 模块如何适应不同设计的示例:通过组合成一个 Activity 来适应平板电脑设计,通过单独Fragment来适应手机设计。

例如—仍然以新闻应用为例—在平板电脑尺寸的设备上运行时,该应用可以在Activity A 中嵌入两个Fragment。不过,在手机尺寸的屏幕上,没有足以储存两个Fragment的空间,因此Activity A只包括用于显示文章列表的Fragment,当用户选择文章时,它会启动Activity B,其中包括用于阅读文章的第二个Fragment。因此,应用可通过重复使用不同组合的Fragment来同时支持平板电脑和手机,如图 1 所示。创建Fragment要想创建Fragment,您必须创建 Fragment 的子类(或已有其子类)。Fragment 类的代码与 Activity 非常相似。它包含与 Activity 类似的回调方法,如 onCreate()、onStart()、onPause() 和 onStop()。实际上,如果您要将现有 Android 应用转换为用Fragment,可能只需将代码从 Activity 的回调方法移入Fragment相应的回调方法中。

系统会在创建Fragment时调用此方法。您应该在实现内初始化您想在Fragment暂停或停止后恢复时保留的必需Fragment组件。

系统会在Fragment首次绘制其用户界面时调用此方法。 要想为您的Fragment绘制 UI,您从此方法中返回的 View 必须是Fragment布局的根视图。如果Fragment未提供 UI,您可以返回 null。

系统将此方法作为用户离开Fragment的第一个信号(但并不总是意味着此片段会被销毁)进行调用。 您通常应该在此方法内确认在当前用户会话结束后仍然有效的任何更改(因为用户可能不会返回)。

大多数应用都应该至少为每个Fragment实现这三个方法,但您还应该使用几种其他回调方法来处理Fragment生命周期的各个阶段。 处理片段生命周期部分对所有生命周期回调方法做了更详尽的阐述。

显示浮动对话框。使用此类创建对话框可有效地替代使用 Activity 类中的对话框帮助程序方法,因为您可以将Fragment对话框纳入由 Activity 管理的Fragment返回栈,从而使用户能够返回清除的Fragment。

要想为Fragment提供布局,您必须实现 onCreateView() 回调方法,Android 系统会在片段需要绘制其布局时调用该方法。您对此方法的实现返回的 View 必须是Fragment布局的根视图。

(2)将作为扩展布局父项的 ViewGroup。传递 container 对系统向扩展布局的根视图(由其所属的父视图指定)应用布局参数具有重要意义;

(3)指示是否应该在扩展期间将扩展布局附加至 ViewGroup(第二个参数)的布尔值。(在本例中,其值为 false,因为系统已经将扩展布局插入 container—传递 true 值会在最终布局中创建一个多余的视图组。)

在本例中,您可以将Fragment当作视图来为其指定布局属性。 例如,以下是一个具有两个Fragment的 Activity 的布局文件:

注:每个Fragment都需要一个唯一的标识符,重启 Activity 时,系统可以使用该标识符来恢复Fragment(您也可以使用该标识符来捕获Fragment以执行某些事务,如将其删除)。

然后,您可以使用 add() 方法添加一个Fragment,指定要添加的Fragment以及将其插入哪个视图。例如:传递到 add() 的第一个参数是 ViewGroup,即应该放置片段的位置,由资源 ID 指定,第二个参数是要添加的Fragment。

如上文所示,您也可以使用 FragmentManager 打开一个 FragmentTransaction,通过它来执行某些事务,如添加和删除片段。执行Fragment事务在 Activity 中使用Fragment的一大优点是,可以根据用户行为通过它们执行添加、删除、替换以及其他操作。您提交给 Activity 的每组更改都称为事务,您可以使用 FragmentTransaction 中的 API 来执行一项事务。您也可以将每个事务保存到由 Activity 管理的返回栈内,从而让用户能够回退Fragment更改(类似于回退 Activity)。

每个事务都是您想要同时执行的一组更改。您可以使用 add()、remove() 和 replace() 等方法为给定事务设置您想要执行的所有更改。然后,要想将事务应用到 Activity,您必须调用 commit()。

不过,在您调用 commit() 之前,您可能想调用 addToBackStack(),以将事务添加到片段事务返回栈。 该返回栈由 Activity 管理,允许用户通过按“返回” 按钮返回上一Fragment状态。

例如,以下示例说明了如何将一个Fragment替换成另一个Fragment,以及如何在返回栈中保留先前状态:

在上例中,newFragment 会替换目前在 R.id.fragment_container ID 所标识的布局容器中的任何Fragment(如有)。通过调用 addToBackStack() 可将替换事务保存到返回栈,以便用户能够通过按“返回” 按钮撤消事务并回退到上一片段。

如果您向事务添加了多个更改(如又一个 add() 或 remove()),并且调用了 addToBackStack(),则在调用 commit() 前应用的所有更改都将作为单一事务添加到返回栈,并且“返回” 按钮会将它们一并撤消。

(2)如果您要向同一容器添加多个Fragment,则您添加片段的顺序将决定它们在视图层次结构中的出现顺序

提示:对于每个Fragment事务,您都可以通过在提交前调用 setTransition() 来应用过渡动画。

调用 commit() 不会立即执行事务,而是在 Activity 的 UI 线程(“主”线程)可以执行该操作时再安排其在线程上运行。不过,如有必要,您也可以从 UI 线程调用 executePendingTransactions() 以立即执行 commit() 提交的事务。通常不必这样做,除非其他线程中的作业依赖该事务。

注意:您只能在 Activity保存其状态(用户离开 Activity)之前使用 commit() 提交事务。如果您试图在该时间点后提交,则会引发异常。这是因为如需恢复 Activity,则提交后的状态可能会丢失。对于丢失提交无关紧要的情况,请使用commitAllowingStateLoss()。与 Activity 通信尽管 Fragment 是作为独立于 Activity 的对象实现,并且可在多个 Activity 内使用,但Fragment的给定实例会直接绑定到包含它的 Activity。

注:尽管您的Fragment会收到与其添加的每个菜单项对应的菜单项选定回调,但当用户选择菜单项时,Activity 会首先收到相应的回调。 如果 Activity 对菜单项选定回调的实现不会处理选定的菜单项,则系统会将事件传递到片段的回调。 这适用于选项菜单和上下文菜单。处理Fragment生命周期管理Fragment生命周期与管理 Activity 生命周期很相似。和 Activity 一样,片段也以三种状态存在:

另一个 Activity 位于前台并具有焦点,但此Fragment所在的 Activity 仍然可见(前台 Activity 部分透明,或未覆盖整个屏幕)。

Fragment不可见。宿主 Activity 已停止,或Fragment已从 Activity 中删除,但已添加到返回栈。 停止Fragment仍然处于活动状态(系统会保留所有状态和成员信息)。 不过,它对用户不再可见,如果 Activity 被终止,它也会被终止。

Activity 生命周期与Fragment生命周期之间的最显著差异在于它们在其各自返回栈中的存储方式。默认情况下,Activity 停止时会被放入由系统管理的 Activity 返回栈(以便用户通过“返回” 按钮回退到Activity,任务和返回栈对此做了阐述)。不过,仅当您在删Fragment的事务执行期间通过调用 addToBackStack() 显式请求保存实例时,系统才会将片段放入由宿主 Activity 管理的返回栈。

在其他方面,管理Fragment生命周期与管理 Activity 生命周期非常相似。 因此,管理 Activity 生命周期的做法同样适用Fragment。 但您还需要了解 Activity 的生命周期对Fragment生命周期的影响。

不过,Fragment还有几个额外的生命周期回调,用于处理与 Activity 的唯一交互,以执行构建和销毁Fragment UI 等操作。这些额外的回调方法是:

不过,当 Activity 离开恢复状态时,Fragment会在 Activity 的推动下再次经历其生命周期。示例为了将本文阐述的所有内容融会贯通,以下提供了一个示例,其中的 Activity 使用两个Fragment来创建一个双窗格布局。 下面的 Activity 包括两个Fragment:一个用于显示莎士比亚戏剧标题列表,另一个用于从列表中选定戏剧时显示其摘要。 此外,它还展示了如何根据屏幕配置提供不同的Fragment配置。

通过使用此布局,系统可在 Activity 加载布局时立即实例化 TitlesFragment(列出戏剧标题),而 FrameLayout(用于显示戏剧摘要的Fragment所在位置)则会占用屏幕右侧的空间,但最初处于空白状态。 正如您将在下文所见的那样,用户从列表中选择某个项目后,系统才会将Fragment放入 FrameLayout。

不过,并非所有屏幕配置都具有足够的宽度,可以并排显示戏剧列表和摘要。 因此,以上布局仅用于横向屏幕配置(布局保存在 res/layout-land/fragment_layout.xml)。

此布局仅包括 TitlesFragment。这意味着,当设备纵向显示时,只有戏剧标题列表可见。 因此,当用户在此配置中点击某个列表项时,应用会启动一个新 Activity 来显示摘要,而不是加载另一个Fragment。

接下来,您可以看到如何在Fragment类中实现此目的。第一个片段是 TitlesFragment,它显示莎士比亚戏剧标题列表。该Fragment扩展了 ListFragment,并依靠它来处理大多数列表视图工作。

3.0以后引入的新的api,为了适配大屏的平板。在普通手机开发的过程中,使用Fragment能实现一个界面的多次使用,能加快效率。Fragment可以被认为是Activity界面的一个布局,其依赖于Activity,但是拥有自己的活动事件与生命周期。可以通过替换Activity中的Fragment实现界面的优化处理。现在And……

Tasks and Back Stack介绍应用通常包含多个Activity。每个 Activity 均应围绕用户可以执行的特定操作设计,并且能够启动其他 Activity。 例如,电子邮件应用可能有一个 Activity 显示新邮件的列表。用户选择某邮件时,会打开一个新 Activity 以查看该邮件。一个 Activity 甚至可以启动设备上其他应用中存在的 Activity。例如…

3.0 中引入了加载器,支持轻松在 Activity 或Fragment中异步加载数据。 加载器具有以下特征:(1)可用于每个 Activity 和 Fragment。(2)支持异步加载数据。(3)监控其数据源并在内容变化时传递新结果。(4)在某一配置更改后重建加载器时,会自动重新连接上一个加载器的 Cursor。 因此…

@[toc]前言因为前一篇关于底部导航BottomNavigationView的使用,所以需要用Fragment来代替之前的activity。作为的一个

新手,因为一直在用activity,几乎没有用到fragment的时候,所以这次要从头开始学习使用。写到fragment的时候想到了Lifecycle和LiveData,用来管理生命周期,但是想了一想决定先不用。因为同时上手多个……

转载请标明出处:自从Fragment出现,曾经有段时间,感觉大家谈什么都能跟Fragment谈上关系,做什么都要问下Fragment能实现不~~~哈哈,是不是有点过~~~本篇博客力求为大家说明Fragment如何产生,什么是Fragment,Fragment生命周期,如何静态和动……

多层嵌套后的 Fragment 懒加载印象中从 Feed 流应用流行开始,Fragment 懒加载变成了一个大家都需要关注的开发知识,关于 Fragment 的懒加载,网上有很多例子,GitHub 上也有很多例子,就连我自己在一年前也写过相关的文章。但是之前的应用可能最多的是一层 Activity + ViewPager 的 UI 层次,但是随着页面越来越复杂,越来越多的应用首页一个页面外层是……

对于新手来说在做分享的时候总会遇到一些问题,现在集成分享也比较多,在网上可以搜到很多关于分享所遇到问题!以微信分享为例,首相要想微信分享需要进入微信的开发者网站点击打开链接,里面会有分享的配置流程和资源下载点击打开链接,不清楚的可以点击连接进行查看。首先我们要创建移动应用,这里比较简单,跟着步骤走就没什么问题,但要注意一点,你填写的包名要与你创建应用的包名一致。…

Fragment和View都有助于界面组件的复用,这在大型工程里边是特别重要的,但是二者又有所区别。1、Fragment的复用粒度更大。Fragment有完整的生命周期,从代码设计角度讲可以提高内聚性,不同情况下还可以设计不同的Fragment,比如横屏和竖屏情况下View的显示不一样,那么可以建立2个不同的Fragment去处理,代码上面可以有效的扩展。从形态上讲和Act…

偶记得第一次接触Fragment,觉得好牛叉的组件,可以做许多Activity可以做的事,辅助Activity让功能可以做得更加强大;一次编写,可以多个地方可以使用,解放了Activity。在这里,本篇文章主要是总结fragment的两种添加方式,add和replace。一、什么是Fragment简单来说,Fragment其实可以理解为一个具有自己生命周期的控件,只不过这个控件又有点特殊,它有自己的…

发表评论

电子邮件地址不会被公开。 必填项已用*标注