Activity内切换fragment实现底部菜单切换遇到的坑

1、一般说来,app底部导航都会设计为5个菜单,可以使用textView,也可使用radioButton,这里我选择用radioButton,给radioButton直接设置selector就可以实现背景变换。

2、接下来说说,fragment切换的实现方式。大家都知道切换fragment有两种方式:

      replace直接替换:

fragmentManager.beginTransaction().replace(R.id.ll_container, fg_home).addToBackStack(null).commitAllowingStateLoss();

   这种方式的特点是,每次切换时,前一个fragment都会执行onDestroyView()方法,新的fragment会重新创建,执行onCreateView()方法。缺点就是每次切换都会重新调用fragment的生命周期,如果在初始化方法里面加载数据的话,势必会重复调用,造成资源浪费。所以我在项目中放弃了这种方式,选择下面第二种方式。但素,话说回来,replace占用资源虽然会多一些,但是不存在add方法的bug。

    ② 另外一种是add方式来进行show和add。使用add方法add到activity里面的fragment的对象并不会被销毁,也就是它仍然在activity中存在,只是应用被置为null而已。此时如果重新为fragment赋值,其hide方法和show方法都不会生效。如果这种情况下,一个activity中有多个fragment,很可能出现多个fragment层叠而不能正常的显示或者隐藏。所以这里使用以下方法来切换:

 1     protected void switchFragmentNoBack(FragmentSociax fragmentInstance) {
 2         currentFragment=fragmentInstance;
 3         FragmentTransaction t = getSupportFragmentManager().beginTransaction();
 4         List<Fragment> fragments = getSupportFragmentManager().getFragments();
 5         if(fragments!=null){
 6             for (int i = 0; i < fragments.size(); i++) {
 7                 FragmentSociax tempFragment = (FragmentSociax) getSupportFragmentManager().findFragmentByTag(fragments.get(i).getClass().getName());
 8                 if (tempFragment != null) {
 9                     if (tempFragment.getClass().getName().equals(fragmentInstance.getClass().getName())) {
10                         t.show(tempFragment);
11                     } else {
12                         t.hide(tempFragment);
13                     }
14                 }
15             }
16         }
17         Fragment fragmentTarget = getSupportFragmentManager().findFragmentByTag(fragmentInstance.getClass().getName());
18         if (fragmentTarget == null && !fragmentInstance.isAdded()) {
19             t.add(R.id.ll_container, fragmentInstance, fragmentInstance.getClass().getName());
20         }
21         t.commitAllowingStateLoss(); 
22     } 

使用了一段时间后,发现友盟上面追踪的有很多fragment already added的崩溃。复现问题,原来快速点击某个tab两次时一定会出现此崩溃。系统解释:

Schedules a commit of this transaction. The commit does not happen immediately; it will be scheduled as work on the main thread to be done the next time that thread is ready.

 意思是刚刚进行的操作没有立即生效,所以解决办法是:调用 getSupportFragmentManager.executePendingTransactions()。放在上面21行代码之后。

 总结:两种方式各有利弊,使用过程中注意规避每种方式里面的坑,正确高效的使用fragment~

  By LiYing

原文地址:https://www.cnblogs.com/widgetbox/p/8320793.html