关于Fragment的那些事儿

Fragment生命周期:

onAttach():当Fragment被加入到activity时被调用(在这个方法中可以获得所在的activity)

onCreate(),

onCreateView():当activity要得到fragment的layout时,调用此方法,fragment在其中创建自己的layout。

onActivityCreate():当activity的onCreate()方法返回后调用此方法。

onStart(),

onResume(),onPause(),onStop(),

onDestoryView():当fragment中的视图被移除的时候,调用这个方法。

onDestory(),

onDetach():当fragment和activity分离的时候,调用这个方法。


Android是通过FragmentManager来管理Fragment,每次对Fragment进行添加和移除时需要开启事务,通过事务处理这些相应的操作,然后commit事务。

添加Fragment方式一:
        FragmentManager fm = getSupportFragmentManager();
        FragmentTransaction tx = fm.beginTransaction();
        tx.add(R.id.content, new Fragment1(),"Fragment1");
        tx.commit();
这里是直接通过add将Fragment1绑定到id为content的View上。


添加Fragment方式二:
        FragmentManager fm = getSupportFragmentManager();
        FragmentTransaction tx = fm.beginTransaction();
        tx.replace(R.id.content, new Fragment1(),"Fragment1");
        tx.commit();

这里使用replace来添加Fragment,replace的作用相当于是remove() + add() 组合后的作用。即使用replace会先移除掉当前id为content上的Fragment,这个被移除掉的Fragment就会被销毁掉(如果当前事务),然后通过add再把新的Fragment添加到View上。


(1)使用replace方式,相当于在对应id为content的FrameLayout上只有一层,那就是上面的Fragment1,通过replace这种方式,会把Fragment的生命周期再走一遍,如果我们的Fragment中有获取数据的操作的话,会频繁的去拉取数据;使用replace,Fragment绑定的视图一定会销毁,Fragment实例不一定会销毁,主要看有没有添加到回退栈。
(2)而通过add方式,我们可以在id为content的FrameLayout上添加多层,也即可以通过多次add来添加多个Fragment到FrameLayout上。这个时候,我们就可以配合hide()、show()方法来不断切换不同的Fragment。在我们通过add方式添加了Fragment到FrameLayout 的View上之后,通过hide()、show()来切换Fragment还有一个优势就是,当一个Fragment重新show展示出来的时候,它原来的数据还保留在该Fragment上,也就是说hide并不会销毁Fragment,只是单纯的隐藏了而已。


推荐方式:
因此,推荐使用add、hide、show的方式管理Fragment。但是这种方式一些情况下也会有一个缺陷就是:可能会造成Fragment重叠。

比如底部有四个Tab:tab1,tab2,tab3,tab4,对应的Fragment引用为tab1Fragment,tab2Fragment,tab3Fragment,tab4Fragment,首先通过add将这四个Fragment添加到FragmentManager后,通过hide和show切换不同TAB都可以处于正常情况,当我们切换到tab1时,假设tab1上的Fragment为 tab1Fragment变量指向的(即tab1Fragment=  new Fragment()),这个时候我们按下HOME键,如果长时间没有回到应用或者内存不足了,系统回收了该引用,此时tab1Fragment= null;但是,tab1的Fragment实例其实还是存在与内存中,只是引用被销毁了,这个时候,我们切换到tab2,这个步骤中,我们会把tab1的fragment隐藏掉,然后显示tab2,即如下操作:
        tx.hide(tab1Fragment);
        tx.show(tab2Fragment);
        tx.commit();
但是,因为此时 tab1Fragment = null,引用变量为空,hide操作无法实现隐藏功能,但是又由于tab1上的Fragment实例还处于内存中,因此此时会造成tab2与tab1重叠的现象。再切换到tab1时,因为tab1Fragment = null,此时会再去创建一个新的Fragment,放入到tab1上,导致原来的tab1上的Fragment一直存在与内存中导致重叠,直至它被回收。

造成上述问题的原因还是因为我们无法找到那个实例对象Fragment,因为引用tab1Fragment已经为空了。这个时候,我们在add的时候可以给Fragment绑定一个tag,用它来标识该Fragment,如果引用为空了,再通过tag来找到该Fragment。如下: 

//在添加Fragment时  
        FragmentManager fm = getSupportFragmentManager();  
        FragmentTransaction tx = fm.beginTransaction();  
        tab1Fragment = new Fragment1();  
        tx.add(R.id.content, tab1Fragment,"fragment1");  
         tx.commit();  
          
        //在使用时,比如切换到tab2时  
        if(tab1Fragment != null){  
            tx.hide(tab1Fragment);  
            tx.show(tab2Fragment);  
            tx.commit();  
        }else{  
            tab1Fragment = (Fragment1) fm.findFragmentByTag("fragment1");  
            tx.hide(tab1Fragment);  
            tx.show(tab2Fragment);  
            tx.commit();  
        }
关于上面的缺陷实例,具体可以看这篇文章:http://blog.csdn.net/shimiso/article/details/44677007



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值