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

  • 相关阅读:
    springboot springcloud zuul 过滤器
    springboot springcloud eureka 熔断器
    javaweb servlet filter
    maven nexus 搭建私服(二)
    springboot springcloud zuul 网关入门
    springboot springcloud 配置中心
    springboot springcloud eureka 入门
    java rabbitmq
    java jvm调优
    maven nexus 搭建私服(一)
  • 原文地址:https://www.cnblogs.com/widgetbox/p/8320793.html
Copyright © 2011-2022 走看看