解决Fragment重影问题(简单粗暴,通俗易懂)

本文详细解析了在Android开发中,使用Fragment时遇到的重影现象及其原因,并提供了一种有效的解决方案,即通过保存Tag的方式在Activity恢复时移除原有Fragment,避免重复绘制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题原因

造成fragment重影的原因是因为我们代码里用add fragment 然后调用hide和show来替换replace方式(因为这样做不用每次切换fragment都重新加载界面和数据)。但是正因为这样当我们activity异常关闭重启时你原先的所有fragment也都会跟着activity重新绘制出来,然而这个时候所有的hide和show失灵了,因为我们默认是没有找到系统帮我们恢复的fragment,而是自己又重新new了一个fragment出来,

解决思路

我的解决思路是采用保存Tag的方式,每添加一个fragment就为它设置一个独立的Tag,就跟ListView复用布局设置Tag是一样的道理,换位思考下就懂了,在Activity恢复时判断通过查找Tag的方式将上次的fragment移除,就可以完美解决重影的问题。

解决步骤

我们在Activity的onCreate中去判断 savedInstanceState 这个参数是否为 null,如果不为null说明Activity为死而复活状态(这时我们要移除前面已经存在的fragment),否则为正常状态,代码如下。

 onCreate方法代码

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.initData(savedInstanceState);
    mManager = getSupportFragmentManager();

    //不为null,说明是死而复活,移除已经存在的fragment
    if (savedInstanceState != null) {
        mTransaction = mManager.beginTransaction();
        mTransaction.remove(mManager.findFragmentByTag(Constant.SOURCE_HEADLINES_TAG));
        mTransaction.remove(mManager.findFragmentByTag(Constant.BUILDING_ONLINE_TAG));
        mTransaction.remove(mManager.findFragmentByTag(Constant.HOME_TAG));
        mTransaction.remove(mManager.findFragmentByTag(Constant.SUN_OPEN_TAG));
        mTransaction.remove(mManager.findFragmentByTag(Constant.WISDOM_CLOUD_TAG));
        mTransaction.commitAllowingStateLoss();
    }

    initFragment();

    //多余代码不再贴出  
    ......
}

  initFragment方法代码

private void initFragment(){
   mTransaction = mManager.beginTransaction();
   mTransaction.add(R.id.fl_fragment_group, mSourceHeadlines, Constant.SOURCE_HEADLINES_TAG);
   mTransaction.add(R.id.fl_fragment_group, mBuildingOnline, Constant.BUILDING_ONLINE_TAG);
   mTransaction.add(R.id.fl_fragment_group, mHome, Constant.HOME_TAG);
   mTransaction.add(R.id.fl_fragment_group, mSunOpen, Constant.SUN_OPEN_TAG);
   mTransaction.add(R.id.fl_fragment_group, mWisdomCloud, Constant.WISDOM_CLOUD_TAG);
   /**
    * 修复Fragment.setNextAnim出现空指针的问题,原因就是没有将Fragment添加到回退栈中,加上下面一行代码即可
    */
   mTransaction.addToBackStack(null);
   mTransaction.hide(mSourceHeadlines);
   mTransaction.hide(mBuildingOnline);
   mTransaction.hide(mSunOpen);
   mTransaction.hide(mWisdomCloud);
   mTransaction.show(mHome);
   mTransaction.commitAllowingStateLoss();
}

  参考: https://blog.youkuaiyun.com/leisurelife1990/article/details/51258749

              https://blog.youkuaiyun.com/jiangtea/article/details/53147172

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值