认识Fragment

原创 2016年08月28日 15:18:52

生命周期

Activity和Fragment比较

Fragment生命周期对比

其实, 上图所体现的Fragment的生命周期只是一部分, 真正的Fragment生命周期更加复杂, 如下图:

Fragment生命周期

生命周期主要的方法回调时机

  • onAttach()
    关联Activity时调用
  • onCreate()
    创建Fragment时调用,在这里必须初始化Fragment的基础组件
  • onCreateView()
    Fragment要绘制自己的界面时调用,这个方法必须返回Fragment的layout,也可以返回null(表示没有界面)
  • onActivityCreated()
    当Activity对象完成自己的onCreate方法时调用
  • onStart()
    Fragment的UI可见时调用
  • onResume()
    Fragment的UI可交互时调用
  • onPause()
    Fragment 可见但不可交互时调用
  • onStop()
    Fragment 完全不可见时调用
  • onDestroyView()
    Fragment 移除视图时调用
  • onDestroy()
    清理View资源时调用
  • onDetach()
    失去Activity关联时调用

Fragment之所以会出现一系列乱七八槽的问题,终究是因为没有弄清楚其生命周期.

Fragment的使用

  • Fragment的使用有两种, 一种是静态使用, 另外一种则是动态使用.
    鸿洋:Android Fragment 真正的完全解析
    鸿洋大神已经很详细的说明了Fragment的使用,还包括了Fragment和Activity之间的通信,Fragment的回退栈等, 所以以下内容仅为本人的一些总结.

静态使用

  1. 将Fragment当作普通的view一样使用, 只需要在Activity布局声明Fragment的节点

    <fragment  
        android:id="@+id/id_fragment_title"  
        android:name="com.zhy.zhy_fragments.TitleFragment"  
        android:layout_width="fill_parent"  
        android:layout_height="45dp" />  
    
  2. 由代码可以看出, 我们需要自定义Fragment的类, 所以我们需要创建一个新的类, 继承Fragment, 并且还要重写onCreateView决定Fragment的布局.

     View view = inflater.inflate(R.layout.fragment_title, container, false);//false表示不替换根布局
    

    这样我们在Activity里就只需要加载它的布局, 不需要对布局进行任何的管理, 因为Fragment都有它自己的生命周期和事件的处理, 这样Activity就变得很干净了呢!

动态使用

因为静态使用局限性太多, 动态的使用Fragment才是我们实际需要的, 例如添加、更新、以及删除和替换 Fragment.
1. 在我们想要使用Fragment的地方声明一个FrameLayout用于放置Fragment

<FrameLayout  
       android:id="@+id/id_content"  
       android:layout_width="fill_parent"  
       android:layout_height="fill_parent" />  

2. 依然需要创建新的类继承Fragment并且加载它的布局.
3. Activity需要做的事情就相比静态使用要多一些了,总共需要5步,必不可少.

  1. 拿到FragmentManagergetFragmentManager()(兼容性写法getSupportFragmentManager()).
  2. 用FragmentManager开启事务beginTransaction(),返回FragmentTransaction对象 (事务是用于解决数据库并发的问题,这里先不关心).
  3. 拥有Fragment对象new Fragment().
  4. 事务替换ft.replace(R.id.container, fragment).即替换容器中的内容.
  5. 事务提交ft.commit();.

链式编程可以简单写成getFragmentManager().beginTransaction().replace(容器id,希望显示的fragment).commit();

FragmentTransaction常用API

Fragment的操作主要都是依靠FragmentTransaction的方法
FragmentTransaction transaction = fm.benginTransatcion();
开启一个事务
add()
往Activity布局的容器中添加一个Fragment
remove()
从Activity中移除一个Fragment,如果被移除的Fragment没有添加到回退栈(回退栈后面会详细说),这个Fragment实例将会被销毁。
replace()
使用另一个Fragment替换当前的,实际上就是remove()然后add()的合体~
hide()
隐藏当前的Fragment,仅仅是设为不可见,并不会销毁
show()
显示之前隐藏的Fragment
detach()
会将view从UI中移除,和remove()不同,此时fragment的状态依然由FragmentManager维护.
remove和detach有一点细微的区别,在不考虑回退栈的情况下,remove会销毁整个Fragment实例,而detach则只是销毁其视图结构,实例并不会被销毁, 如果你的当前Activity一直存在,那么在不希望保留用户操作的时候,你可以优先使用detach, 因为不需要重新创建实例.
attach()
重建view视图,附加到UI上并显示.
commit()
提交一个事务,特别需要注意的是,如果遇到Activity状态不一致:State loss这样的错误. 主要是因为:commit方法一定要在Activity.onSaveInstance()之前调用.

Fragment回退栈

在提交事务之后, 即当前Fragment已经不能看见, 如果你想通过返回键再回退到当前Fragment, 就需要在提交事务之前和replace之后, 将当前Fragment通过事务调用addToBackStack(String)添加到了回退栈. 但是replace之后, 当前Fragment的视图层次依然会被销毁,即会调用onDestoryView和onCreateView, View视图所保存的内容将会丢失, 所以如果不希望视图层被销毁, 就不能调用replace方法, 而是调用 hide 和 add方法.
Fragment的回退栈是由FragmentManager来管理的.

管理Fragment回退栈

  • getSupportFragmentManager().getBackStackEntryCount() -获取回退栈中实体数量
  • getSupportFragmentManager().popBackStack(String name, int flags) -根据name立刻显示对应的Fragment, 在其栈之上的fragment都会被销毁.
  • getSupportFragmentManager().popBackStack(int id, int flags) -同理

Fragment的通信

鸿洋: Android Fragment 真正的完全解析(下)中可以看出, 利用Fragment来开启另外一个Fragment的方式是不可取的. 当需要从一个Fragement里面的内容中跳转到另外一个Fragment, 应当由Fragment的管理者Activity来操作.
总的来说, 为了降低Fragment与Activity的耦合, Fragment和Activity之间的通信基本上是基于接口的回调, 这是我们在使用时所推荐使用的.

使用Fragment常见问题

  • 点击返回键出现白板
    不需要将所有的Fragment都添加到了回退栈.
  • 两个Fragment重叠在一起
    1. 当Fragment长时间置于后台, 系统有可能会回收掉, 当你重新打开, 即Activity重新启动时, 又重新绘制了一次Fragment, 所以就会出现重叠.
    2. 当屏幕发生旋转,Activity发生重新启动,默认的Activity中的Fragment也会跟着Activity重新创建, 这样造成当旋转的时候,本身存在的Fragment会重新启动,然后当执行Activity的onCreate时,又会再次实例化一个新的Fragment
    3. 解决: 检查onCreate的参数Bundle savedInstanceState就可以判断,当前是否发生Activity的重新创建. 和Activity类似,Fragment也有onSaveInstanceState的方法,在此方法中进行保存数据,然后在onCreate或者onCreateView或者onActivityCreated进行恢复都可以.
版权声明:本文为博主原创文章,随意转载

相关文章推荐

认识Android中的Fragment

在实际开发中LayoutInflater这个类还是非常有用的,它的作用类似于findViewById()。不同点是LayoutInflater是用来找res/layout/下的xml布局文件,并且实例...

Fragment生命周期新认识

文章内容也许与标题并不是很相符,我主要想写的只是在项目中遇到的一些小问题以及问题的是如何解决,至于写这个标题只是因为这些错误是由于对Fragment的生命周期理解不够深刻而导致的。 为了便于分析,贴出...

安卓中Fragment的认识

Fragment:Activity片段    a)Fragment的特点:     (1)Fragment作为Activity界面的一部分组成出现     (2)可以在一个Activi...

懒加载Fragment

  • 2017-10-10 18:59
  • 24.15MB
  • 下载

Android开发——Fragment简单示例(一)认识Fragment

昨天和大家说过我们有一次重大考试对吧,这个学期唯一一门考试课,今天上午考完了,很多人是不是觉得考完了很开心呀,可以各种浪啦。博主把情况和你们说一说你们会觉得超级开心。博主之前也说过我们这个学期技术实战...

fragment+web

  • 2017-03-21 20:21
  • 993KB
  • 下载

点击切换fragment

  • 2016-03-21 15:07
  • 2.98MB
  • 下载

android fragment保存数据

不能用 replace 应该是 add replace()的调用会导致Fragment的onCreteView()被调用,所以切换界面时会无法保存当前的状态。因此一般采用add()、hide...

first_fragment

  • 2016-04-13 15:12
  • 5.41MB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)