简述Android Fragment

目录:
[TOC]

Fragment的生命周期

  • onAttach()
    当Fragment与Activity发生关联时调用。

  • onCreate()
    当创建Fragment实例时,系统回调的方法。在该方法中,需要对一些必要的组件进行初始化,以保证这个组件的实例在Fragment处于pause或stop状态时仍然存在。

  • onCreateView()
    当第一次在Fragment上绘制UI时,系统回调的方法。该方法返回一个View对象,该对象表示Fragment的根视图;若Fragment不需要展示视图,则该方法可以返回null。

  • onActivityCreated()
    当Activity的onCreate()返回时调用。

  • onStart()

  • onResume()

  • onPause()
    当用户离开Fragment时回调的方法(并不意味着该Fragment被销毁)。在该方法中,可以对Fragment的数据信息做一些持久化的保存工作,因为用户可能不再返回这个Fragment。

  • onShop()

  • onDestoryView()
    与onCreateView想对应,当该Fragment的视图被移除时调用。

  • onDestory()
    当Fragment销毁时调用。

  • onDetach()
    与onAttach相对应,当Fragment与Activity关联被取消时调用。

注意:除了onCreateView(),其他的所有方法如果你重写了,必须调用父类对于该方法的实现。

将Fragment加入Activity的两种方式

  • 静态使用
    使用fragment标签,将Fragment当成普通的控件,直接写在Activity的布局文件中,用布局文件调用Fragment。

    1. 继承Fragment,重写onCreateView设置Fragemnt的布局文件;
    2. 在Activity的布局文件中,使用标签<fragment name=""/>,属性android:name指定Fragment的全限定类名;
    3. 在Activity中声明此Fragment,就当和普通的View一样。
  • 动态使用

    1. 继承Fragment,重写onCreateView设置Fragemnt的布局文件;
    2. 在Activity的布局文件中,使用标签 <FrameLayout/>;
    3. 在Activity中实例化此Fragment;
    4. 获取FragmentManager对象,并通过FragmentManager对象获取FragmentTransaction对象;
    5. 通过FragmentTransaction对象的方法将实例化Fragment,添加到在Activity的布局文件的标签<FrameLayout/>容器中。

FragmentManager

主要用于在Activity中操作Fragment。

  • 获取方式

    • Android 3.0以上版本:getFragmentManager()
    • Android 3.0以下版本:getSupportFragmentManager()
    • 注意:
      使用Android3.0以下的版本,需要引入v4的包,然后Activity继承FragmentActivity,然后通过getSupportFragmentManager获得FragmentManager。
    • 建议:
      将Menifest文件的uses-sdk的minSdkVersion和targetSdkVersion都改为11以上,这样就不必引入v4包了。**
  • fragmentManager.beginTransaction()

    • add()
      往Activity中添加一个Fragment。

    • remove()
      从Activity中移除一个Fragment,remove会销毁整个Fragment实例。

    • replace()
      使用另一个Fragment替换当前的,实际上就是先执行remove()然后执行add()。

    • hide()
      隐藏当前的Fragment,仅设为不可见,并不会销毁。

    • show()
      显示之前隐藏的Fragment。

    • detach()
      会将View从UI中移除,和remove()不同,此时Fragment的状态依然由FragmentManager维护。

    • attach()
      重建View视图,附加到UI上并显示。只是销毁其视图结构,实例并不会被销毁。

    • commit()
      一定要在Activity.onSaveInstance()之前调用。

    • 注意:
      当使用add(),show(),hide()跳转新的Fragment时,旧的Fragment回调onHiddenChanged(),不会回调onStop()等生命周期方法,而新的Fragment在创建时是不会回调onHiddenChanged(),这点要切记。

Fragment回退栈

  • 入栈
    FragmentTransaction.addToBackStack(String)

  • 栈顶出栈
    getFragmentManager().popBackStack()

  • 获取栈内数目
    getFragmentManager().getBackStackEntryCount()

  • 场景1:
    Fragment_A add() 启动 Fragment_B add()
    Fragment_A replce() 启动 Fragment_B add()

    • Fragment_A:
      onAttch() onCreate() onCreateView() onActivityCreate() onStart() onResume()
    • Fragment_B:
      onAttch() onCreate() onCreateView() onActivityCreate() onStart() onResume()
    • Back键: 退出应用
      • Fragment_A: onPause()
        Fragment_B: onPause()
        Fragment_A: onStop()
        Fragment_B: onStop()
        Fragment_A: onDestoryView() onDestory() onDetach()
        Fragment_B: onDestoryView() onDestory() onDetach()
  • 场景2:
    Fragment_A add() 启动 Fragment_B replce()
    Fragment_A replce() 启动 Fragment_B replce()

    • Fragment_A:
      onAttch() onCreate() onCreateView() onActivityCreate() onStart() onResume() onPause() onStop() onDestoryView() onDestory() onDetach()
    • Fragment_B:
      onAttch() onCreate() onCreateView() onActivityCreate() onStart() onResume()
    • Back键: 退出应用
      • Fragment_B: onPause() onStop() onDestoryView() onDestory() onDetach()
  • 场景3:Fragment_A add() 启动 Fragment_B replce() addToBackStack()

    • Fragment_A: onAttch() onCreate() onCreateView() onActivityCreate() onStart() onResume() onPause() onStop() onDestoryView()
    • Fragment_B: onAttch() onCreate() onCreateView() onActivityCreate() onStart() onResume()
    • Back键: 回退到Fragment_A
      • Fragment_B: onPause() onStop() onDestoryView() onDestory() onDetach()
        Fragment_A: onCreateView() onActivityCreate() onStart() onResume()
  • 场景4:Fragment_A add() addToBackStack() 启动 Fragment_B add()

    • Fragment_A:
      onAttch() onCreate() onCreateView() onActivityCreate() onStart() onResume()
    • Fragment_B:
      onAttch() onCreate() onCreateView() onActivityCreate() onStart() onResume()
    • Back键:
      • 第一次:回退到Fragment_A
        • Fragment_A:
          onPause() onStop() onDestoryView() onDestory() onDetach()
      • 第二次:退出应用
        • Fragment_B:
          onPause() onStop() onDestoryView() onDestory() onDetach()
  • 场景5:Fragment_A add() addToBackStack() 启动 Fragment_B replce()

    • Fragment_A:
      onAttch() onCreate() onCreateView() onActivityCreate() onStart() onResume() onPause() onStop() onDestoryView()
    • Fragment_B:
      onAttch() onCreate() onCreateView() onActivityCreate() onStart() onResume()
    • Back键:
      • 第一次:销毁Fragment_A
        • Fragment_A:
          onDestory() onDetach()
      • 第二次:退出应用
        • Fragment_B
          onPause() onStop() onDestoryView() onDestory() onDetach()
  • 场景6:Fragment_A add() addToBackStack() 启动 Fragment_B add() addToBackStack()

    • Fragment_A:
      onAttch() onCreate() onCreateView() onActivityCreate() onStart() onResume()
    • Fragment_B:
      onAttch() onCreate() onCreateView() onActivityCreate() onStart()
    • Back键:
      • 第一次:销毁Fragment_B
        • Fragment_B:
          onPause() onStop() onDestoryView() onDestory() onDetach()
      • 第二次:销毁Fragment_A
        • Fragment_A:
          onPause() onStop() onDestoryView() onDestory() onDetach()
      • 第三次:退出应用
  • 场景7:Fragment_A replce() addToBackStack() 启动 Fragment_B replce()

    • Fragment_A:
      onAttch() onCreate() onCreateView() onActivityCreate() onStart() onResume() onPause() onStop() onDestoryView()
    • Fragment_B:
      onAttch() onCreate() onCreateView() onActivityCreate() onStart() onResume()
    • Back键:
      • 第一次:销毁Fragment_A
        • Fragment_A:
          onDestory() onDetach()
      • 第二次:销毁Fragment_B并退出应用
        • Fragment_B:
          onPause() onStop() onDestoryView() onDestory() onDetach()

Fragment通信

  • Fragment获取Activity的数据

    • getActivity()
      在Fragment中可以通过getActivity()得到当前绑定的Activity的实例,然后进行操作。
      注:如果在Fragment中需要Context,可以通过调用getActivity(),如果该Context需要在Activity被销毁后还存在,则使用getActivity().getApplicationContext()。

    • newInstance()
      使用newInstance(参数)创建Fragment对象,优点是调用者只需要关系传递的哪些数据,而无需关心传递数据的Key是什么。

    • setArguments()
      创建Fragment对象,使用setArguments()方法存入数据,在onCreateView()中通过getArguments()取出数据。

  • Activity获取Fragment的数据

    • public方法
      如果Activity中包含自己管理的Fragment的引用,可以通过引用直接访问所有的Fragment的public方法。

    • TAG或者ID
      如果Activity中未保存任何Fragment的引用,但每个Fragment都有一个唯一的TAG或者ID,可以通过getFragmentManager.findFragmentByTag()或者findFragmentById()获得任何Fragment实例,然后进行操作。

  • Fragment和Fragment

    • 同宿主
      setTargetFragment()

      • 使用场景:
        当前A_Fragment启动B_Fragment,B_Fragment在完成操作后返回数据的。
      • 执行流程:
        A_Fragment使用setTargetFragment()方式启动B_Fragment,完成操作,B_Fragment通过 getTargetFragment().onActivityResult(),调用A_Fragment的onActivityResult()获取返回值。
    • 不同宿主
      startActivityForResult()

      • 使用场景:
        存在于不同Activity中的Fragment,A_Fragment点击跳转到B_Fragment中,B_Fragment操作结束并且希望它将结果返回,在A_Fragment显示。
        在Fragment中存在startActivityForResult()以及onActivityResult(),没有setResult(),用于设置返回的intent,需要通过调用getActivity().setResult()。
        Fragment能够从Activity中接收返回结果,但是自身无法返回结果,只有Activity拥有返回结果。
      • 执行流程:
        首先,A_Fragment的startActivityForResult()跳转到B_Fragment;
        其次,B_Fragment中获取A_Fragment传递的参数,执行一些操作;
        然后,B_Fragment调用getActivity().setResult(),进行设置返回的数据;
        最后,在A_Fragment的onActivityResult()拿到返回结果进行回显。

FragmentActivity和Activity的区别

Fragment是Android 3.0以后推出的,为了在低版本中使用Fragment就需要用到android-support-v4.jar兼容包,而FragmentActivity就是这个兼容包里面的,它提供了操作Fragment的一些方法,其功能跟Android 3.0及以后的版本的Activity的功能一样。

Fragment设置唯一标识的方式

  1. 通过android:id属性为fragment指定唯一ID;
  2. 通过android:tag属性为fragment指定唯一字符串标识;
  3. 若上述两种凡是均未指定,则该fragment的标识为其父容器控件的ID。

FragmentPagerAdapter与FragmentStatePagerAdapter

  • FragmentPagerAdapter
    对于不再需要的Fragment,选择调用detach方法,仅销毁视图,并不会销毁Fragment实例。
  • FragmentStatePagerAdapter
    销毁不再需要的Fragment,当当前事务提交以后,会彻底的将Fragment从当前Activity的FragmentManager中移除,state标明,销毁时,会将其onSaveInstanceState()中的bundle信息保存下来,当用户切换回来,可以通过该bundle恢复生成新的Fragment,可以在onSaveInstanceState(Bundle outState)方法中保存一些数据,在onCreate中进行恢复创建。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,332评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,508评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,812评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,607评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,728评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,919评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,071评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,802评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,256评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,576评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,712评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,389评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,032评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,026评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,473评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,606评论 2 350