Fragment的使用笔记

使用v4包里的Fragment与android.app.Fragment的差别在于:

  1. v4包的兼容支持3.0以下版本
  2. v4包的Activity必须继承自android.support.v4.app.FragmentActivity
  • 必须使用FragmentActivity.getSupportFragmentManager获取FragmentManager,framework里的Fragment则使用Activity.getFragmentManager即可

使用方法

1. 最简单的用法,使用Android studio 新建一个Activity 使用Fragment作为内容


这个时候就会自动生成<fragment>标签,像View一样的使用,其中android:name设置为我们的Fragment类所在路径。

<fragment android:id="@+id/fragment"
          android:name="pagename.FragmentName"
          android:layout_width="match_parent"
          android:layout_height="match_parent"/>

2. 通过在Activity 实例化Fragment,然后使用fragmentTransaction.add添加到containerView

        mFragment = new MyFragment();
        FragmentManager fragmentManager = getSupportFragmentManager();
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        fragmentTransaction.add(R.id.containerViewId, mFragment);
        fragmentTransaction.commit();

3. 多个fragment 动态选择显示在Activity里面

在方法 二的基础上,只要使用以下代码进行Fragment的切换
replace这个方法,可清除所有已经添加到容器View里面的Fragment,然后再添加我们传入的Fragment。

FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.containerViewId, mFragment2);
fragmentTransaction.commit();

4. 多个Fragment通过ViewPager显示在Activity里面

  • 首先需要继承 FragmentPagerAdapter 或者 FragmentStatePagerAdapter必须实现或重写其中的

区别:FragmentPagerAdapter 内的每一个生成的 Fragment 都将保存在内存之中,因此适用于那些相对静态的页,数量也比较少的那种;如果需要处理有很多页,并且数据动态性较大、占用内存较多的情况,应该使用FragmentStatePagerAdapter。
正如其类名中的 'State' 所表明的含义一样,该 PagerAdapter 的实现将只保留当前页面,当页面离开视线后,就会被消除,释放其资源;而在页面需要显示时,生成新的页面(就像 ListView 的实现一样)。这么实现的好处就是当拥有大量的页面时,不必在内存中占用大量的内存。

   /**
    * Return the number of views available.   
    */   
  public abstract int getCount();

   /**
    * Return the Fragment associated with a specified position.
    */
   public abstract Fragment getItem(int position);

  • 然后在Activity将Adapter设置到Viewpager里面就可以了
FragmentManager fm = getSupportFragmentManager();
mAdapter = new VpAdapter(fm);
mViewPager.setAdapter(mAdapter);
  • ViewPager和
    android.support.design.widget.TabLayout更配哦
    /**
    *  重写Adapter的这个方法,使TabLayout可以关联显示ViewPager每一页的Title
    */
    public CharSequence getPageTitle(int position);

    //通过以下代码关联TabLayout和ViewPager
    mTabLayout.setupWithViewPager(mViewPager);
    mTabLayout.setTabsFromPagerAdapter(mAdapter);

Fragment的简单介绍

生命周期

Fragment必须是依存与Activity而存在的,官网这张图很好的说明了两者生命周期的关系

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

Fragment 常用的API

Fragment常用的三个类:
Fragment 主要用于定义Fragment
FragmentManager 主要用于在Activity中操作Fragment
FragmentTransaction 保证一些列Fragment操作的原子性
主要的操作都是FragmentTransaction的方法
FragmentTransaction transaction = fm.benginTransatcion();//开启一个事务
**transaction.add() **往Activity中添加一个Fragment
**transaction.remove() **从Activity中移除一个Fragment,如果被移除的Fragment没有添加到回退栈(回退栈后面会详细说),这个Fragment实例将会被销毁。
transaction.replace()使用另一个Fragment替换当前的,实际上就是remove()然后add()的合体~
transaction.hide()隐藏当前的Fragment,仅仅是设为不可见,并不会销毁
transaction.show()显示之前隐藏的Fragment
transaction.detach()会将view从UI中移除,和remove()不同,此时fragment的状态依然由FragmentManager维护。
transaction.attach()重建view视图,附加到UI上并显示。
transatcion.commit()提交一个事务

Fragment栈管理

通过FragmentTransaction.addToBackStack()可以将事务添加进回退栈中(back stack),这样在事务提交之后,可以从栈中再将这个事务中取出(即退按后退键可以回到原来的状态)

  FragmentManager fragmentManager = getSupportFragmentManager();
  FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
  mFragment2 = new MainActivityFragment2();
  fragmentTransaction.replace(R.id.fragment, mFragment2);
  fragmentTransaction.addToBackStack(null);
  fragmentTransaction.commit();

注意Fragment被remove之后View会被销毁,不管是否有添加到栈中,所以比如在Fragment中有输入一些数据,销毁后再回退回去,双重新createView则原来Fragment中的输入的数据将会丢失,这种场景下,可以使用transaction.hide()然后再**transaction.add() **新的Fragment,这样才回退的时候,才能完整恢复原来的Fragment。

Fragment与Activity通信

因为Fragment是依附于Activity的,所以通信起来并不复杂

  1. 使用Fragment的引用(通过实例化new 出来,或者通过FragmentManager.findFragmentByTag() 和 findFragmentById()获取),可以通过引用直接访问所有的Fragment的public方法
  2. Fragment中可以通过getActivity()得到当前绑定的Activity的实例,然后进行操作访问Activity的所有public方法。
  3. Fragment需要Context,可以通过调用getActivity(),如果该Context需要在Activity被销毁后还存在,则使用getActivity().getApplicationContext()
  • 广播,EventBus等方法进行通信
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,117评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,963评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 107,897评论 0 240
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,805评论 0 203
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,208评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,535评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,797评论 2 311
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,493评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,215评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,477评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,988评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,325评论 2 252
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,971评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,055评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,807评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,544评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,455评论 2 266

推荐阅读更多精彩内容