0.  前言

Fragment,顾名思义是片段的意思,可以把Fragment当成Activity的一个组成部分,甚至Activity的界面可以完全有不同的Fragment组成。Fragment需要被嵌套到Activity上面才能起作用,Fragment可以充分利用屏幕面积,而且也可以更方便用户进行交互操作。Fragment是在Android3.0(API level 11)引入的,如果你要适配之前的系统,需要先导入Android-support-v4的jar包,继承FragmentActivity并通过getSupportFragmentManager获得FragmentManager。

1.  Fragment声明周期


Fragment的生命周期和Activity很像,只是多了几个方法如下所示。需要注意的是,因为Fragment是依附于Activity的,所以Activity的生命周期会影响到Fragment的生命周期,如下onActivityCreated()的调用时机就说明了这一点。还有比如,如果Activity是暂停状态,其中所有的Fragment都是暂停状态。如果Activity被销毁,那么它其中的所有Fragment都会被销毁。

//当Fragment被绑定到Activity时被调用
onAttach()
//创建该Fragment的视图,最常用,除了这个方法其余方法调用都需要super
onCreateView()
//当Activity的onCreate方法返回时调用
onActivityCreated()
//移除Fragment的布局时被调用,跟onCreateView()对应
onDestroyView()
//当Fragment跟Activity解除关联时被调用,跟onAttach()对应
onDetach()

2.  Fragment的使用方式

2.1  静态方式

静态方式是把Fragment当成普通的控件,直接写在Activity的布局文件中。

首先写一个类继承Fragment,重写onCreateView,使用inflate决定Fragemnt的布局。

public class MyFragment extends Fragment    {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
View view = inflater.inflate(R.layout.myfragment, container, false);
return view;
}
}

最后直接在Activity中布局文件中声明此Fragment,就当和普通的View一样使用即可。

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<fragment
android:id="@+id/myfragment"
android:name="com.example.seucalvin.MyFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>

2.2  动态方式

动态方式可以灵活地添加、更新、以及删除Fragment,首先将Activity的布局设置为空。

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/id_content ">
</FrameLayout>

这里结合具体例子体现代码中的逻辑。有时候,我们可能有这样的需求,比如京东商城APP中导航栏每个按钮对应一个fragment,当用户按下BACK键,会先判断若不是首页的fragment则回到首页的fragment,再按下BACK才会退出应用,达到了比较好的用户体验效果。这就需要用到Fragment的回退栈。

首先需要将Fragment1添加进Activity的FrameLayou中,在Activity的onCreate()中进行逻辑控制。这里我们使用add()对Fragment进行了动态的加载。具体API功能可以参考下文的总结。

FragmentTransaction ft= getFragmentManager().beginTransaction();
ft.add(R.id.id_content, new FragmentOne(),"ONE");
ft.commit();

接着将介绍从Fragment1跳转到Fragment2的按钮逻辑,假设该按钮在Fragment1上。

public class FragmentOne extends Fragment implements OnClickListener {
private Button mBtn;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_one, container, false);
mBtn = (Button) view.findViewById(R.id.fragment_one_btn);
mBtn.setOnClickListener(this);
return view;
}
@Override
public void onClick(View v) {
FragmentTwo two = new FragmentTwo();
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(R.id.id_content, fTwo, "TWO");
ft.addToBackStack(null);
ft.commit();
}
}

这个逻辑跳转Fragment2中,使用了replace()方法,replace是remove和add的合体,如果Fragment1没有被添加到回退栈,跳转时Fragment1实例会被销毁。上面源码中倒数第二行我们调用了tx.addToBackStack(null)将Fragment1添加到了回退栈,所以Fragment1实例不会被销毁,但是视图层次依然会被销毁,即会调用onDestoryView和onCreateView,即当我们按下BACK键回到Fragment1时,Fragment1上诸如EditText上曾经编辑的文字会消失。那么如何保证曾经的输入还在呢?可以如下这样写点击逻辑。

 public void onClick(View v)  {
FragmentTwo two = new FragmentTwo();
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.hide(this);
ft.add(R.id.id_content, fTwo, "TWO");
ft.addToBackStack(null);
ft.commit();
}

这里没有使用replace,而是先hide当前Fragment,再添加Fragment2实例,最后Fragment1添加到回退栈,这样即可实现文字的保留。

接下来实现,无论接下来Fragment2在进入Fragment3、4、5,用户点击Back键,直接回到Fragment1,如果直接在主界面Fragment1则直接退出的逻辑:

public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
// 获取当前回退栈中的Fragment个数
int backStackEntryCount = fragmentManager.getBackStackEntryCount();
if (backStackEntryCount > 1) {
// 如果回退栈中Fragment个数大于1则一直退出
while (fragmentManager.getBackStackEntryCount() > 1) {
fragmentManager.popBackStackImmediate();
}
} else {
finish();
}
}
return true;
}

3  API介绍

这一小节介绍Fragment相关的API。这些常用API的作用还是要熟悉的。

//获取FragmentManage的方式,v4包中为getSupportFragmentManager
getFragmentManager()
//开启一个事务,并添加/删除一个Fragment
//从Activity中remove一个Fragment时,如果被移除的Fragment没有添加到回退栈,这个Fragment实例将会被销毁,而后面的detach则不会销毁实例,只是销毁其视图结构
FragmentTransaction transaction = fm.benginTransatcion();
transaction.add()
transaction.remove()
transatcion.commit()//提交一个事务,一定要在Activity.onSaveInstance()之前调用
//使用另一个Fragment替换当前的,实际上就是remove()然后add()的合体
transaction.replace()
//隐藏/显示当前的Fragment,隐藏仅仅是设为不可见,并不会销毁
transaction.hide()
transaction.show()
//会将view从UI中移除, fragment的状态依然由FragmentManager维护
detach()
//重建view视图,附加到UI上并显示
attach()

下面的API是关于回退栈的,均为fm所调用。

//将Fragment添加到回退栈中
addToBackStack(tag)
//如果i=0则回退到该tag所对应的Fragment层
//如果i=FragmentManager.POP_BACK_STACK_INCLUSIVE则回退到该tag所对应的Fragment的上一层
popBackStack(String tag, int i)
//立即清除回退栈中栈顶Fragment
popBackStackImmediate()
//获取回退栈中Fragment的个数
getBackStackEntryCount()
//获取回退栈中该索引值下的Fragment
//若为fragmentManager.getBackStackEntryCount() – 1即获取当前Fragment节点,继续getName()即可获得该节点tag标记
getBackStackEntryAt(int index)

下一篇Android开发——Fragment知识整理(二)将着重于介绍Fragment和Activity之间的通信以及使用Fragment保存Activity销毁时数据的一些知识。

Android开发——Fragment知识整理(一)的更多相关文章

  1. Android开发——Fragment知识整理(二)

    0.  前言 Android开发中的Fragment的应用非常广泛,在Android开发--Fragment知识整理(一)中简单介绍了关于Fragment的生命周期,常用API,回退栈的应用等知识.这 ...

  2. 阿里内部资料:Android开发核心知识笔记共2100页,58万字,完整版开放下载

    作为一个3-5年的Android工程师,我们经常会遇到这些瓶颈: 1.技术视野窄长期在小型软件公司,外包公司工作,技术视野被限制的太厉害 2.薪资提升难初中级Android岗位薪资上升空间有限,基本上 ...

  3. Android开发——Fragment的简单使用总结

    前言: 之前搞项目的时候,就使用了这个Fragment,中间遇到了许多坑,把坑都解决了,现在写一篇较为简单的Fragment使用总结 Fragment的简单介绍: 简单来说,Fragment其实可以理 ...

  4. 移动端 Web 开发前端知识整理

    文章来源: http://www.restran.net/2015/05/14/mobile-web-front-end-collections/ 最近整理的移动端 Web 开发前端知识,不定期更新. ...

  5. 【Bugly 技术干货】Android开发必备知识:为什么说Kotlin值得一试

    1.Hello, Kotlin Bugly 技术干货系列内容主要涉及移动开发方向,是由 Bugly邀请腾讯内部各位技术大咖,通过日常工作经验的总结以及感悟撰写而成,内容均属原创,转载请标明出处. 1. ...

  6. 安卓巴士Android开发神贴整理

    10个经典的Android开源应用项目 http://www.apkbus.com/android-13519-1-1.html 安卓巴士总结了近百个Android优秀开源项目,覆盖Android开发 ...

  7. Android开发 ---Fragment片段布局

    前言 Fragment想必大家不陌生吧,在日常开发中,对于Fragment的使用也很频繁,现在主流的APP中,基本的架构也都是一个主页,然后每个Tab项用Fragment做布局,不同选项做切换,使用起 ...

  8. Android开发Fragment的使用学习

    基本概念 Fragment是Android3.0(API11)提出的概念,support-v4库中也开发了一套Fragment API,最低兼容Android 1.6.所以在开发中要注意不要导错包 导 ...

  9. Android 开发必备知识:我和 Gradle 有个约会

    腾讯Bugly特约作者:霍丙乾 0.讲个故事 0.1 Ant,我还真以为你是只蚂蚁 真正开始近距离接触编程其实是在2012年,年底的时候带我的大哥说,咱们这个 app 发布的时候手动构建耗时太久,研究 ...

随机推荐

  1. 用sparkR, 分析上亿条订单数据的脚本。

    上周我们这个10人的小团队开发的推荐拉新系统, 日拉新人数已接近4万人.过去几个月这个系统从无到有, 拉新从日增几千稳步增长到日增几万, 同事们几个月来,每天工作13个小时以上,洗澡时间都没有, 有时 ...

  2. centos7 修改中文字符集

    CentOS 7字符集的问题与6有点区别,会出现下面问题,查看是中文,vi进入就变成乱码了 生产中修改配置文件   [root@ce1d2002a999 ~]# cat /etc/locale.con ...

  3. C# 泛型约束 xxx<T> Where T:约束(一)

    泛型约束 代码举例 发现我们游戏的代码中,主程写了很多类似这样的代码: public static T CreateObject<T>(out int objectId) where T ...

  4. [IDEA_3] IDEA 配置 GitHub 并上传项目

    0. 说明 参考 Git & GitHub 的安装配置 IDEA 配置 GitHub 并上传项目 1. 安装配置 Git & GitHub 参照 Git & GitHub 的安 ...

  5. Linux uptime命令详解

    常见的命令展示 uptime 08:21:34 up 36 min, 2 users, load average: 0.00, 0.00, 0.00 #当前服务器时间: 08:21:34 #当前服务器 ...

  6. 2.2Python基础语法(二)之运算符

    返回总目录 目录: 1.Python运算符的分类 2.算数运算符 3.复合运算符 4.比较运算符 5.逻辑运算符 (一)Python运算符的分类: (二)算数运算符: 注意下面三种算数符号: 1.** ...

  7. DevExpress06、Popup Menus、RadialMenu、XtraTabControl、SplitContainerControl、GroupControl

    Popup Menus 弹出菜单 使用弹出菜单(popup menus),我们可以在   控件上   显示   上下文选项   或  命令. 弹出菜单是一个显示了特定项的窗体,用户可以选择这些项以执行 ...

  8. 写博的第一天 0x00

    作为一个大学生,我觉得自己除了睡觉,打游戏,吃饭更应该做点有意义的事情,作为计算机专业的学生,更应该勤奋点,主动去学习.已经要大三了,我认识到这个暑假我必须学点什么了,为了更好的学习,我决定学语言的同 ...

  9. FZU Monthly-201901 tutorial

    FZU Monthly-201901 tutorial 题目(难度递增) easy easy-medium medium medium-hard hard 思维难度 AHG F B CE D 编码难度 ...

  10. python第四十四课——继承性之单继承

    2.继承性 继承: 使用场景: 1).生活层面:... 2).计算机层面: 两部分组成,一部分我们称为父类(基类.超类.superclass),另一部分我们称为子类(派生类.subclass), 子类 ...