浅谈Fragment
2019独角兽企业重金招聘Python工程师标准>>>
概述
你可以认为一个fragment相当于activity的一个模块部分,它可以有自己的生命周期,接收自己的输入事件,甚至可以在activity运行期间添加和删除(有点像可以在不同activity中重用的子activity)
你可以依赖Support V4 Library来使用Fragment,V4包提供了很多很有用的东西。V4包提供的Fragment可以向下兼容到Android 1.6 (API Level 4),如果你的最低API Level > = 11的话就没必要使用V4包了,官方在11之后就引入了Fragment类。大多数时候我们还是要使用V4的,谁叫它里面有个ViewPager呢!
Note:如果你想在API Level 11以下使用Fragment,那么你的
Activity
就应该继承FragmentActivity
了,FragmentActivity
是Support Library中用来兼容API Level 11以下在Activity中处理Fragment的特殊的Activity。如果你同时使用了V7 appcompat library
,你应该继承AppCompatActivity
,它是FragmentActivity
的子类。
向Activity添加Fragment
你可以在XML布局文件中使用<fragment/>
标签插入fragment
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:orientation="horizontal"android:layout_width="fill_parent"android:layout_height="fill_parent"><fragment android:name="com.example.android.fragments.HeadlinesFragment"android:id="@+id/headlines_fragment"android:layout_weight="1"android:layout_width="0dp"android:layout_height="match_parent" /></LinearLayout>
很方便,但是有局限性,如果我们想要使用Bundle
向HeadLinesFragment
传入一些值时,这种方式显得无能为力,你也可以在运行时向Activity添加Fragment,这个时候你需要知道这个类FragmentManager
。FragmentManager
提供了一些使你在运行时添加、移除和替换Fragment的方法,以便为用户提供一种动态体验,而且,如果你打算在运行周期内更改Fragment,就必须这样做。
你必须使用FragmentManager
创建一个FragmentTransaction
开启事务来执行添加、移除、替换以及使用其他事务API操作。如果你的Activity是FragmentActivity
的子类,那么调用 getSupportFragmentManager()
以获取 FragmentManager
,然后调用beginTransaction()
创建 FragmentTransaction
。
另一个向Activity的XML布局文件插入Fragment的方式就是使用<FrameLayout/>
标签,这种布局一次只会显示一个Fragment。
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"android:id="@+id/fragment_container"android:layout_width="match_parent"android:layout_height="match_parent" />
在Activity中添加Fragment
public class MainActivity extends FragmentActivity {@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.news_articles);getSupportFragmentManager().beginTransaction().add(R.id.fragment_container, new HeadlinesFragment()).commit();}}
抽象层面上看,FrameLayout
是作为一个容器来使用,可以为这个容器添加多个Fragment,最后添加的显示在最上层,注意add和replace的区别:
- add是把一个fragment添加到一个容器中
- replace是先remove容器里所有的fragment,然后再add目标fragment。
如果你希望允许用户向后导航,例如用户执行替换或移除Fragment等事务时,能够向后导航和“撤销”所做更改,事务提交之前调用addToBackStack()
Note: 当你移除或替换 Fragment 并向返回堆栈添加事务时,已移除的 Fragment 会停止(而不是销毁)。如果用户向后导航,还原该 Fragment,它会重新启动。如果你没有向返回堆栈添加事务,那么该 Fragment 在移除或替换时就会被销毁。
addToBackStack()
方法可接受可选的字符串参数,来为事务指定独一无二的名称。除非你打算使用FragmentManager.BackStackEntry
API 执行高级 Fragment 操作,否则无需使用此名称。
Note: 调用
commit()
不会立即执行事务,而是在 Activity 的 UI 线程(“主”线程)可以执行该操作时再安排其在线程上运行。不过,如有必要,您也可以从 UI 线程调用executePendingTransactions()
以立即执行commit()
提交的事务。通常不必这样做,除非其他线程中的作业依赖该事务
Note: 你只能在 Activity保存其状态(用户离开 Activity)之前使用
commit()
提交事务。如果您试图在该时间点后提交,则会引发异常。 这是因为如需恢复 Activity,则提交后的状态可能会丢失。 对于丢失提交无关紧要的情况,请使用commitAllowingStateLoss()
。
Fragment间的通信
为了能够重复利用Fragment UI组建,你最好将每一个Fragment设计成拥有自己的布局和行为的完全独立的模块化组件,你的Activity构建就是一场积木游戏。不同模块间少不了事件交流,例如点击一个评论,底栏输入框的hint就会显示“回复 @XXX”(加入你设计的二者不在一个Fragment)
为了让Fragment间通信,你可以下Fragment内部定义一个接口,在Activity实现它,不用麻烦的传入值,Fragment在生命周期方法onAttach()
就可以捕获到它
public class HeadlinesFragment extends ListFragment {OnHeadlineSelectedListener mCallback;public interface OnHeadlineSelectedListener {public void onArticleSelected(int position);}@Overridepublic void onAttach(Activity activity) {super.onAttach(activity);try {mCallback = (OnHeadlineSelectedListener) activity;} catch (ClassCastException e) {throw new ClassCastException(activity.toString() + " must implement OnHeadlineSelectedListener");}}
}
向操作拦添加项目
您的片段可以通过实现 onCreateOptionsMenu()
向 Activity 的选项菜单(并因此向操作栏)贡献菜单项。不过,为了使此方法能够收到调用,您必须在 onCreate()
期间调用 setHasOptionsMenu()
,以指示片段想要向选项菜单添加菜单项(否则,片段将不会收到对 onCreateOptionsMenu()
的调用)。
您之后从片段添加到选项菜单的任何菜单项都将追加到现有菜单项之后。 选定菜单项时,片段还会收到对 onOptionsItemSelected() 的回调。
您还可以通过调用 registerForContextMenu()
,在片段布局中注册一个视图来提供上下文菜单。用户打开上下文菜单时,片段会收到对onCreateContextMenu()
的调用。当用户选择某个菜单项时,片段会收到对 onContextItemSelected()
的调用。
Note: 尽管您的片段会收到与其添加的每个菜单项对应的菜单项选定回调,但当用户选择菜单项时,Activity 会首先收到相应的回调。 如果 Activity 对菜单项选定回调的实现不会处理选定的菜单项,则系统会将事件传递到片段的回调。 这适用于选项菜单和上下文菜单。
Fragment的生命周期
Fragment必须始终嵌入在 Activity 中,其生命周期直接受宿主 Activity 生命周期的影响。 例如,当 Activity 暂停时,其中的所有片段也会暂停;当 Activity 被销毁时,所有片段也会被销毁。
与Activity生命周期类似,Fragment也只能在三种状态下停留:
- Resumed: Fragment在运行中的Activity可见
- Paused: 另一个 Activity 位于前台并具有焦点,但此片段所在的 Activity 仍然可见(前台 Activity 部分透明,或未覆盖整个屏幕)。
- Stopped: Fragment不可见。宿主 Activity 已停止,或片段已从 Activity 中删除,但已添加到返回栈。 停止片段仍然处于活动状态(系统会保留所有状态和成员信息)。 不过,它对用户不再可见,如果 Activity 被终止,它也会被终止。
同样与 Activity 一样,假使 Activity 的进程被终止,而您需要在重建 Activity 时恢复片段状态,您也可以使用 Bundle 保留片段的状态。您可以在片段的 onSaveInstanceState()
回调期间保存状态,并可在 onCreate()
、onCreateView()
或 onActivityCreated()
期间恢复状态。
Activity 生命周期与片段生命周期之间的最显著差异在于它们在其各自返回栈中的存储方式。 默认情况下,Activity 停止时会被放入由系统管理的 Activity 返回栈。不过,仅当您在删除片段的事务执行期间通过调用 addToBackStack()
显式请求保存实例时,系统才会将片段放入由宿主 Activity 管理的返回栈。
Note: 如需 Fragment 内的某个 Context 对象,可以调用
getActivity()
。但要注意,请仅在片段附加到 Activity 时调用getActivity()
。如果片段尚未附加,或在其生命周期结束期间分离,则getActivity()
将返回 null。
转载于:https://my.oschina.net/ClaireChris/blog/527694
浅谈Fragment相关推荐
- 浅谈 LiveData 的通知机制
LiveData 和 ViewModel 是 Google 官方的 MVVM 架构的一个组成部分.巧了,昨天分析了一个问题是 ViewModel 的生命周期导致的.今天又遇到了一个问题是 LiveDa ...
- 浅谈Android保护技术__代码混淆
浅谈Android保护技术__代码混淆 浅谈Android保护技术__代码混淆 代码混淆 代码混淆(Obfuscated code)亦称花指令,是将计算机程序的代码,转换成一种功能上等价,但是难于阅读 ...
- 浅谈 URI 及其转义
浅谈 URI 及其转义 URI URI,全称是 Uniform Resource Identifiers,即统一资源标识符,用于在互联网上标识一个资源,比如 https://www.upyun.com ...
- android 存储空间监控,浅谈 Android 内存监控(中)
前言 在上篇 浅谈 Android 内存监控(上) 中,我们聊了 LeakCanary,微信的 Matirx 和美团的 Probe,它们各自有不同的应用场景,例如,在开发测试环境,我们会偏向用 Lea ...
- 浅谈人工智能:现状、任务、构架与统一
引言 第一节 现状:正视现实 第二节 未来:一只乌鸦给我们的启示 第三节 历史:从"春秋五霸"到"战国六雄" 第四节 统一:"小数据.大任务&q ...
- 浅谈Android Architecture Components
浅谈Android Architecture Components 浅谈Android Architecture Components 简介 Android Architecture Componen ...
- html 怪异模式,CSS_浅谈CSS编程中的怪异模式,怪异模式盒模型
今天学习了 - phpStudy...
浅谈CSS编程中的怪异模式 怪异模式盒模型 今天学习了一下css3的box-sizing属性,顺便又温习了一下css的盒模型,最后觉得有必要对盒模型做一个全面整理. 先不考虑css3的情况,盒模型一共 ...
- 浅谈 git 底层工作原理
浅谈 git 底层工作原理 系统复习到这里也快差不多了,大概就剩下两三个 sections,这里学习一下 git 的 hashing 和对象. 当然,跳过问题也不大. config 文件 这里还是会用 ...
- 浅谈Android中的MVP与动态代理的结合
浅谈Android中的MVP与动态代理的结合 本篇文章已授权微信公众号 guolin_blog (郭霖)独家发布 在Android开发平台上接触MVP足足算起来大概已经有一个年头左右.从最开始到现在经 ...
最新文章
- R语言使用回归方法解决方差分析问题
- iOs 自定义UIView 日历的实现 Swift2.1
- pwm调制 matlab仿真,PWM脉冲调制直流电机的simulink仿真
- 分割视图控制器(UISplitViewController)
- 河南职称计算机啥时间考试,河南省2020年高级职称考试时间与具体安排
- SpringBoot自学汇总
- 台湾印象之一:金马奖之夜
- 效率 用div做表格和tr_头一次见用电钻做电线接线,效率高出十倍,用几十年都不漏电...
- 笨方法学python --习题12
- 给大学生的劝告——你们为何应该开始接触UNIX/Linux
- 在校大学生研究生软著申请详解及模板下载
- 兼容性问题以及解决方案
- Windows域的创建与加入教程
- css 实现一个尖角_css3如何做尖角标签效果?
- python实现LU分解与LUP分解
- python爬去新浪微博_GitHub - dataabc/weiboSpider: 新浪微博爬虫,用python爬取新浪微博数据...
- 小程序后端云开发(一)
- 第一篇:微信公众平台开发实战Java版之了解微信公众平台基础知识以及资料准备...
- 《互联网时代》第四集 再构
- e339 java_java-在Spring Mongo中从文档数组中删除项目
热门文章
- 【pytest】Hook 方法之 pytest_addoption :注册命令行参数
- mysql删除emp表的语句_MySQL删除数据表(DORP TABLE语句)
- html5 视口,html5 – 在媒体查询中更改视口
- es 模糊查询_ES系列11:Term-level queries 之 3种模糊查询和terms_set query
- java面向服务架构_面向服务的体系架构 SOA(一) --- 基于TCP、HTTP协议的RPC
- Tomcat Caused by java lang OutOfMemoryError PermGen space
- 安卓学习笔记38:利用OpenGL ES绘制旋转立方体
- 无心剑中译叶芝诗17首
- SciTE文本编辑器初体验
- 【JSOI2007】【BZOJ1029】【codevs2913】建筑抢修,贪心与堆