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