关于Fragment重叠问题(二)

一、问题描述

相信大家在使用Fragment的过程中,肯定碰到过Fragment重叠的问题,重启应用就好了。然而原因是什么呢?

二、原因分析

首先,Android管理Fragment有两种方式,使用add、hide、show的方式和replace方式,两种方式各有优缺点。

  1. replace方式
    如果使用这种方式,是可以避免重叠的问题,但是每次replace会把生命周期全部执行一遍,如果在这些生命周期函数 里拉取数据的话,就会不断重复的加载刷新数据,所以我们并不推荐使用这种方式。

  2. add、hide、show的方式
    虽然这种方式避免了可能重复加载刷新数据的问题,但是会出现重叠的问题。

原因:

当系统内存不足,Fragment 的宿主 Activity 回收的时候,Fragment 的实例并没有随之被回收。Activity 被系统回收时,会主动调用 onSaveInstance() 方法来保存视图层(View Hierarchy),所以当 Activity 通过导航再次被重建时,之前被实例化过的 Fragment 依然会出现在 Activity 中,此时的 FragmentTransaction 中的相当于又再次 add 了 fragment 进去的,hide()和show()方法对之前保存的fragment已经失效了,所以就出现了重叠。
然而我们还是推荐使用这个,我们可以解决。

三、问题重现

既然要解决问题,自然要重现一下!
1.手机的 “设置” - “开发者选项” - 打开”不保留活动”(主要用于模拟Activity被及时回收)
2.把 app 切换到后台,再重新打开,通过点按不同的 tab 来切换 Fragment
这里写图片描述

四、解决方法

方法一、简单暴力

通过注释掉这句话,这样主 Activity 因为种种原因被回收的时候就不会保存之前的 fragment state

@Override
protectedvoidonSaveInstanceState(Bundle outState) {
//如果用以下这种做法则不保存状态,再次进来的话会显示默认tab
//总是执行这句代码来调用父类去保存视图层的状态
//super.onSaveInstanceState(outState);
}
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
方法二、(推荐使用)

重写onAttachFragment,重新让新的Fragment指向了原本未被销毁的fragment,它就是onAttach方法对应的Fragment对象

    @Override
    public void onAttachFragment(Fragment fragment) {
        if (tab1 == null && fragment instanceof Tab1Fragment)
            tab1 = fragment;
        if (tab2 == null && fragment instanceof Tab2Fragment)
            tab2 = fragment;
        if (tab3 == null && fragment instanceof Tab3Fragment)
            tab3 = fragment;
        if (tab4 == null && fragment instanceof Tab4Fragment)
            tab4 = fragment;
    }

 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
方法三

思路同样是阻止系统恢复Fragment state,在FragmentActivity保存所有Fragment状态前把Fragment从FragmentManager中移除掉。

    protected void onSaveInstanceState(Bundle outState) {
        FragmentTransaction transaction = fm.beginTransaction();
        transaction.remove(tab1);
        transaction.remove(tab2);
        transaction.remove(tab3);
        transaction.remove(tab4);
        transaction.commitAllowingStateLoss();
        super.onSaveInstanceState(outState);
    }
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

这里写图片描述

成功解决,ok,o(∩_∩)o ,希望可以帮助有需要的同学,如果觉得好,欢迎留个言啊!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值