大话Fragment管理

  上一个项目遇到了一个Activity 管理30个Fragment的情况,刚开始的时候真的管理的焦头烂额,但是后来不停的研究api文档,渐渐的明白了android的Fragment管理体系。下面用一种Fragment嵌套Fragment的情况来总结一下Fragment的管理。

150223103.jpg

spacer.gif  大神立马就能看出来,最外面一个Activity,底下首页,分类,购物车..是第一层一个FragmentTabHost,而首页里面的类别01,02....是用的开源库TabPageIndicator管理的ViewPager,管理这第二层的n个Fragment。
  1.当遇到这种嵌套多层的Fragment的时候第一个主要点就是第一层的FragmentManager,可以通过getSupportFragmentManager()或者getFragmentManager()获得,但是在第二层的fragment中如果想获得FragmentManager就不能这样了,必须用getChildFragmentManager()。
  2.当点击一个其中一个商品的详情的时候,如果想保持底部的TabHost那就不能用Activity,还得保持Fragment,其实还有另一中方案,那就是最外面的Activity用TabHostActivity,为什么没用尼,因为TabHostActivity已经被废弃了,当我看到那条废弃的横线时,就好像看到一个美女脸上被刀开花了一样,心痛啊,不能娶这样的媳妇啊,直接换FragmentTabHost,黄花大闺女,唉呀妈呀,老装逼了。回到需求,当点击其中一个商品时候,要将底部的TabHost保持,上面的布局都换成详情的布局,看下Api,FragmentTransaction提供add,replace俩个方法,那么用add还是replace尼?使用add()加入fragment时将触发onAttach(),使用attach()不会触发onAttach(),使用replace()替换后会将之前的fragment的view从viewtree中删除。
  触发顺序:
  detach()->onPause()->onStop()->onDestroyView()
  attach()->onCreateView()->onActivityCreated()->onStart()->onResume()
  使用hide()方法只是隐藏了fragment的view并没有将view从viewtree中删除,随后可用show()方法将view设置为显示
  而使用detach()会将view从viewtree中删除,和remove()不同,此时fragment的状态依然保持着,在使用attach()时会再次调用onCreateView()来重绘视图,注意使用detach()后fragment.isAdded()方法将返回false,在使用attach()还原fragment后isAdded()会依然返回false(需要再次确认)
  执行detach()和replace()后要还原视图的话, 可以在相应的fragment中保持相应的view,并在onCreateView()方法中通过view的parent的removeView()方法将view和parent的关联删除后返回。
  3.在复杂的Fragment管理中,经常会遇到 Fragment already added 错误,解决这样的错误方法就是,每次添加Fragment,先findFragmentByTag,如果找到了fragment.isAdded(),那么就return,跳出,如果Fragment没在栈中,那就把Fragment Add上去,下面放出一个Fragment管理的公用类
  java代码

/**
 * Fragment跳转
 * @param fm
 * @param fragmentClass
 * @param tag
 * @param args
 */
public void turnToFragment(FragmentManager fm, Class<? extends Fragment> fragmentClass, String tag, Bundle args) {
    mIsCanEixt = false;
    Fragment fragment = fm.findFragmentByTag(tag);
    boolean isFragmentExist = true;
    if (fragment == null) {
        try {
            isFragmentExist = false;
            fragment = fragmentClass.newInstance();
            fragment.setArguments(new Bundle());
        } catch (java.lang.InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }
    if(fragment.isAdded()){
        return;
    }
    if( args != null && !args.isEmpty() ) {
        fragment.getArguments().putAll(args);
    }
    FragmentTransaction ft = fm.beginTransaction();
    ft.setCustomAnimations(android.R.anim.fade_in, android.R.anim.fade_out,
            android.R.anim.fade_in, android.R.anim.fade_out);
    if( isFragmentExist ) {
        ft.replace(R.id.realtabcontent, fragment);
    } else {
        ft.replace(R.id.realtabcontent, fragment, tag);
    }
                               
    ft.addToBackStack(tag);
    ft.commitAllowingStateLoss();
}


最后为什么用

ft.commitAllowingStateLoss();

而不是

ft.commit();尼?commitAllowingStateLoss和commit的区别是当退出activity时,防止提交后的状态丢失。对于你觉得可以丢失提交的状况,使用 commitAllowingStateLoss(

详见:http://m.blog.csdn.net/blog/xujinyang1234/11711865

你可能感兴趣的:(管理,Fragment,方式)