Android Fragment生命周期

来源:互联网 发布:拼长图不损画质的软件 编辑:程序博客网 时间:2024/06/05 16:44

注:如果使用Android3.0以下的版本,需要引入v4的包,然后Activity继承FragmentActivity,然后通过getSupportFragmentManager获得FragmentManager。
[java] view plaincopy
  1. FragmentManager fm = getFragmentManager();  
  2. FragmentTransaction transaction = fm.beginTransaction();  
  3. mWeixin = new ContentFragment();            
  4. transaction.replace(R.id.id_content, mWeixin);  
  5. transaction.addToBackStack(null);  
  6. transaction.commit();  

说明:如果在ContentFragment中点击了back那么直接回到当前fragment,因为当前事务加入了回退栈,同时当前fragment生命周期为onDestroyView-onCreateView。
如果注释transaction.addToBackStack(null);说明当前事务不加入回退栈,那么ContentFragment中点击了back直接退出该activity,同时
当前fragment生命周期onDestroyView-onDestroy-onDetach,因为执行了replace,会销毁实例


transaction方法生命周期表现

transaction.remove()
从Activity中移除一个Fragment,如果被移除的Fragment没有添加到回退栈(回退栈后面会详细说),这个Fragment实例将会被销毁。被销毁的意思是会重新从onDestroyView-onDestroy-onDetech-onAttach,onCreate,onCreateView-onActivityCreate开始,但是如果添加到了回退栈,那么实例不会销毁只是销毁视图,调用onDestroyView-nCreateView-onActivityCreate

transaction.replace()
使用另一个Fragment替换当前的,实际上就是remove()然后add()的合体~
onDestroyView-onDestroy-onDetech-onAttach,onCreate,onCreateView-onActivityCreate

transaction.hide()
隐藏当前的Fragment,仅仅是设为不可见,并不会销毁
hide的话都不会去销毁视图,既不会调用onDestroyView方法

transaction.show()
显示之前隐藏的Fragment

detach()
会将view从UI中移除,和remove()不同,此时fragment的状态依然由FragmentManager维护,会销毁视图,但是不会销毁实例。

attach()
重建view视图,附加到UI上并显示。

b、如果Activity中未保存任何Fragment的引用,那么没关系,每个Fragment都有一个唯一的TAG或者ID, 可以通过getFragmentManager.findFragmentByTag()或者findFragmentById()获得任何 Fragment实例,然后进行操作。
mLeftMenuFragment = (LeftMenuFragment) fm.findFragmentById(R.id.id_left_menu_container);
        if (mLeftMenuFragment == null) {
            mLeftMenuFragment = new LeftMenuFragment();
            fm.beginTransaction().add(R.id.id_left_menu_container, mLeftMenuFragment).commit();
        }

//查找当前显示的Fragment
mCurrentFragment = (ContentFragment) fm.findFragmentByTag(mTitle);

if (mCurrentFragment == null) {
    mCurrentFragment = ContentFragment.newInstance(mTitle);
    fm.beginTransaction().add(R.id.id_content_container, mCurrentFragment, mTitle).commit();
}

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

通信最佳方式

 虽然Fragment和Activity可以通过getActivity与findFragmentByTag或者findFragmentById,进 行任何操作,甚至在Fragment里面操作另外的Fragment,但是没有特殊理由是绝对不提倡的。Activity担任的是Fragment间类似 总线一样的角色,应当由它决定Fragment如何操作。另外虽然Fragment不能响应Intent打开,但是Activity可 以,Activity可以接收Intent,然后根据参数判断显示哪个Fragment。
Fragment中
[java] view plaincopy
  1. public interface FOneBtnClickListener {  
  2.     public void onFOneBtnClick();  
  3. }  
  4.   
  5. public void setfBtnClickListener(FOneBtnClickListener fBtnClickListener) {  
  6.     this.fBtnClickListener = fBtnClickListener;  
  7. }  
  8. public void onClick(View v) {  
  9.     // TODO Auto-generated method stub  
  10.     fBtnClickListener.onFOneBtnClick();  
  11. }  
Activity中
[java] view plaincopy
  1. Fragment fragmentOne = new FragmentOne();  
  2. ((FragmentOne) fragmentOne). setfBtnClickListener(this);  
  3. fragmentTransaction.add(R.id. content, fragmentOne, null);  
  4. fragmentTransaction.commit();  
 

Fragment屏幕旋转

不断的旋转屏幕,你会发现每旋转一次屏幕,屏幕上就多了一个FragmentOne的实例,并且后台log会打印出许多套生命周期的回调。
Activity发生重新启动,默认的Activity中的Fragment也会跟着Activity重新创建;这样造成当旋转的时候,本身存在的 Fragment会重新启动,然后当执行Activity的onCreate时,又会再次实例化一个新的Fragment,这就是出现的原因。

那么如何解决呢:其实通过检查onCreate的参数Bundle savedInstanceState就可以判断,当前是否发生Activity的重新创建:

Fragment跟宿主Activity之间的解耦

 比如我们某个按钮触发Activity跳转,需要通过Intent传递参数到目标Activity的Fragment中,那么此Fragment如何获取当前的Intent的值呢?
[java] view plaincopy
  1. @Override  
  2. public void onCreate (Bundle savedInstanceState ) {  
  3.     // TODO Auto-generated method stub  
  4.     super.onCreate( savedInstanceState);  
  5.   
  6.     Bundle bundle = getArguments();  
  7.     if (bundle != null) {  
  8.         argString = bundle.getString( ARG);  
  9.     }  
  10. }  
  11.   
  12. public static FragmentOne newInstance(String argument) {  
  13.     Bundle bundle = new Bundle();  
  14.     bundle.putString(ARG, argument);  
  15.   
  16.     FragmentOne fragmentOne = new FragmentOne();  
  17.     fragmentOne.setArguments( bundle);  
  18.   
  19.     return fragmentOne;  

0 0
原创粉丝点击