zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    Mootools遮罩层练习(原为网上的jquery写法)
    Notepad++ c编译环境 64
    Apache添加多端口
    数据库权限分配(远程共享数据库)(mysql)
    Zend studio13 导入已有php文件夹
    按钮js跳转到非表单提交页
    Sql case when 小例
    php 获取数组中的key值
    knit使用安装 ecstore knit位置 及调用路径
    python数据库操作
  • 原文地址:https://www.cnblogs.com/widgetbox/p/8320793.html
Copyright © 2011-2022 走看看