认识Fragment

生命周期

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进行恢复都可以.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值