Fragment使用详解

  • 基本使用
    • 静态使用Fragment
    • 动态使用Fragment
  • Fragment是什么
    • 生命周期
    • 返回栈
    • 常用API
      • 管理Fragment
      • 执行Fragment事务
  • Fragment 的状态保存和恢复
  • 其它使用
    • Fragment与Activity的交互、传设置View的参数
    • 如何与ActionBar,MenuItem集成
    • 兼容大屏幕
    • 没有视图的Fragment的用处

系列
Fragment (一):Fragment使用详解
Fragment (二):Activity 和Fragment 的异常销毁、状态保存和恢复机制
Fragment (三):源码解析Fragment 返回栈原理

基本使用


静态使用Fragment

步骤:
1、继承Fragment,重写onCreateView()决定Fragemnt的布局。
2、在activity的xml中使用fragment标签加入该类,就当和普通的View一样。

activity的xml文件:

<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/id_fragment_title"  
        android:name="com.zhy.zhy_fragments.TitleFragment"  
        android:layout_width="fill_parent"  
        android:layout_height="45dp" />  

    <fragment  
        android:layout_below="@id/id_fragment_title"  
        android:id="@+id/id_fragment_content"  
        android:name="com.zhy.zhy_fragments.ContentFragment"  
        android:layout_width="fill_parent"  
        android:layout_height="fill_parent" /> 
RelativeLayout>

‹fragment› 标签中的 android:name 属性指定要在布局中实例化的 Fragment 类。

每个Fragment都需要一个唯一的标识符,重启 Activity 时,系统可以使用该标识符来恢复Fragment(也可以使用该标识符来捕获Fragment以执行某些事务,如将其删除)。 可以通过三种方式为Fragment提供 ID:
为 android:id 属性提供唯一 ID
为 android:tag 属性提供唯一字符串
如果未给以上两个属性提供值,系统会使用容器视图的 ID

动态使用Fragment

通过编程方式将Fragment添加到某个现有 ViewGroup 。
在activity中:

FragmentManager fragmentManager = getFragmentManager()
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
FragmentA fragment = new FragmentA();
fragmentTransaction.add(R.id.fragment_container, fragment);
fragmentTransaction.commit();

Fragment是什么


生命周期

概念
A Fragment is a piece of an application’s user interface or behavior that can be placed in an Activity. Interaction with fragments is done through FragmentManager, which can be obtained via Activity.getFragmentManager() and Fragment.getFragmentManager().

Fragment 表示 Activity 中的部分行为或UI。Fragment拥有自己的生命周期,但其生命周期受它所在Activity影响。Fragment有自己的Fragment返回栈。

Fragment使用详解_第1张图片
Fragment的生命周期(其 Activity 运行时)。

Fragment使用详解_第2张图片
Activity 生命周期对Fragment生命周期的影响。

可以看到Fragment比Activity多了几个额外的生命周期回调方法:

  • onAttach(Activity):当Fragment与Activity发生关联时调用。
  • onCreateView(LayoutInflater, ViewGroup,Bundle):创建该Fragment的视图
  • onActivityCreated(Bundle):当Activity的onCreate方法返回时调用
  • onDestoryView():与onCreateView想对应,当该Fragment的视图被移除时调用
  • onDetach():与onAttach相对应,当Fragment与Activity关联被取消时调用
    注意:除了onCreateView,其他的所有方法如果你重写了,必须调用父类对于该方法的实现。

Activity 生命周期与Fragment生命周期之间的最显著差异在于它们在其各自返回栈中的存储方式。

返回栈

Fragment返回栈:存放的是Fragment事务,栈顶事务出栈实质上就是对该事务进行逆操作

Fragment返回栈与Activity返回栈区别与联系:

  • 区别:默认情况下,Activity 停止时会被放入由系统管理的 Activity 返回栈(以便用户通过“返回” 按钮回退到Activity)。不过,Fragment只有在Fragment的事务执行期间通过调用 addToBackStack() 显式请求保存实例时,系统才会将Fragment事务放入由宿主 Activity 管理的Fragment返回栈。栈顶元素出栈时,Activity返回栈是直接将栈顶的Activity显示到屏幕而Fragment返回栈则要先对栈顶的事务进行逆操作,并将操作结果显示在屏幕上。

  • 联系:两者都是返回栈,栈顶“元素”出栈时删除屏幕上原来的“元素”并将栈顶元素显示在屏幕上做为前台“元素”。都可以通过按返回键实现出栈操作。
    注意:前台“元素”(即当前屏幕上显示的“元素”)是不在返回栈中的。

常用API

管理Fragment

  • 概念:
    要想管理Activity中的Fragment,需要使用FragmentManager。FragmentManager用于管理被添加的Fragment。

  • 获取FragmentManager:
    调用Activity或被添加的Fragment的getFragmentManager() // v4中,getSupportFragmentManager()。若是在FragmentA中添加FragmentB则须在FragmentA中通过getChildFragmentManager()获取。

    注意:FragmentManager只管理它的直接子结点。通过调用Activity或被添加的Fragment的getFragmentManager() 获得的是管理该Activity下所有被添加的Fragment(不包括这些Fragment中的子Fragment)。通过调用FragmentA的getChildFragmentManager()获取的是管理FragmentA下所有被添加的Fragment(不包括这些Fragment中的子Fragment)。树形结构:Activity就是根,所有active fragment(“前台”fragment 和返回栈中的fragment)都是子结点。每个结点都持有FragmentManager,用于管理它的直接子结点。

“前台”fragment:调用了add()但既没有被销毁也尚未被移到返回栈中的fragment 。

FragmentManagerImpl 中有两个重要的Field:

  1. mAdded:fragment列表,保存所有前台fragment 。
  2. mActive:fragment列表,保存所有前台fragment 和返回栈中的fragment ,实际上就是active fragment。
  • FragmentManager 常用API:
    • 获取Fragment:通过findFragmentById()(对于在 Activity 布局中提供UI 的Fragment)或 findFragmentByTag()(对于提供或不提供 UI 的Fragment)获取 Activity 中存在的Fragment。
    • popBackStack():(模拟用户发出的 Back 命令)将Fragment从返回栈中弹出。
    • addOnBackStackChangedListener(): 注册一个侦听返回栈变化的侦听器。
    • beginTransaction():打开一个FragmentTransaction,通过它来执行某些事务,如添加和删除Fragment。

执行Fragment事务

  • add() 向Activity中添加一个Fragment。
  • remove() 从Activity中移除一个Fragment。若被移除的Fragment被添加到回退栈,则只是销毁该Fragment的视图(其实就是detach()),生命周期调用到onDestroyView(),不会调用onDestroy()、onDetach()去销毁自己,依然由FragmentManager维护;如果没有则这个Fragment实例将会被销毁。
  • replace() 使用另一个Fragment替换当前的,实际上就是remove()然后add()的合体。
  • hide() 隐藏当前的Fragment,仅仅是设为不可见,不会调用生命周期回调方法。
  • show() 显示之前隐藏的Fragment,不会调用生命周期回调方法。
  • detach() 会将view从UI中移除,和remove()不同,此时fragment的状态依然由FragmentManager维护(即fragment仍然是active的)。
  • attach() 重建view视图,附加到UI上并显示。
  • addToBackStack() 将事务添加到Fragment返回栈中,回退时其实就是事务的逆操作。
  • commit() 提交事务。

Fragment 的状态保存和恢复


无论是Activity还是Fragment,View状态想要实现自动保存,View必须设置了id。此外,textview还需要声明android:freezeText=”true”才能保存和恢复状态。

在Fragment 中引发状态保存和恢复有两种情形:
1. 异常销毁。
2. 事务进出返回栈。

1、异常销毁
Activity的异常销毁会导致它所管理的所有active fragment 的异常销毁。fragment的异常销毁会触发自身的onSaveInstanceState(),同时还会自动保存View 状态。
异常销毁发生后,用户再次回到该Activity会重建该Activity,同时之前的所有active fragment 也会被重建,在此过程中会自动恢复Fragment 的View状态,同时,用户可在onCreate() 或onActivityCreated() 中恢复Fragment 状态。

注意:异常销毁时Activity会被销毁,用户回到该Activity时,系统除了会自动重建该Activity,还会自动重建销毁前的 active fragment ,但其他Activity 持有的fragment 不会被自动重建。这些重建的fragment 全部都是show 状态。

2、事务进出栈
Fragment事务进入Fragment返回栈会自动保存进入返回栈的Fragment的View状态(注:在这一过程中不会调用onSaveInstanceState()),出栈时会自动恢复View状态。

更详细的介绍参考:Activity 、Fragment 的异常销毁、状态保存和恢复机制

其它使用


Fragment与Activity的交互、传设置View的参数

参考:Android Fragment 真正的完全解析(下)

如何与ActionBar,MenuItem集成

参考:Android Fragment 真正的完全解析(下)

兼容大屏幕

在Activity中,已拥有FragmentA,若开启FragmentB时为兼容大屏幕必须:

  1. 分别为大屏和小屏提供各自的xml布局文件。
  2. 静态使用时,通过findFragmentById()或findFragmentByTag()判断Activity中是否有FragmentB的对象。动态使用时,通过findViewById()判断Activity中是否有存放该FragmentB的布局。

没有视图的Fragment的用处

参考:fragment 状态保存和恢复


本文参考:Fragment 用法总结(一)

你可能感兴趣的:(Fragment使用详解)