fragment重叠的实用解决方案

1、问题分析

大部分的App基本的架构就是底部按钮和fragment结合的,但是在使用的时候手机横竖屏、以及内存不够回收Activity会出现fragment重叠的问题

问题原因:fragment的生命周期是依附于Activity的但是在Activity销毁时,fragment的信息被Activity的方法onSavedInstanceState()保存到内存中,当再代开App的时候界面会出现重叠的情况

2、问题解决

(在Androidmainfest.xml中的Activity添加

android:configChanges="orientation|keyboardHidden|screenSize"
//如果不是平板可直接设置竖屏

2.1简单粗暴方法

重写onSaveInstanceState()方法

@Override
    public void onSaveInstanceState(Bundle outState, PersistableBundle outPersistentState) {
//        super.onSaveInstanceState(outState, outPersistentState);//直接注销即可
    }


//或者
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    ......

    if (savedInstanceState != null) {
        mCustomVariable = savedInstanceState.getInt("variable", 0);
    }
}

@Override
protected void onSaveInstanceState(Bundle outState) {
    //super.onSaveInstanceState(outState);
    outState.putInt("variable", mCustomVariable);
}

这样重写之后,相当于不会调用Activity的onSaveInstanceState的方法保存系统默认数据,只保存自己需要的数据。Activity异常销毁时不会保存Fragment,当然也就不会再有重叠的问题出现。 
不过这样处理是可能出现问题的,Activity的onSaveInstanceState方法不仅仅只是保存Fragment,还会保存获取焦点的View的状态,ActionBar,以及调用View的onSaveInstanceState 保存View的相关数据。

2.2、给每个Fragmet界面的根布局设置默认背景和拦截的点击事件

android:background="@android:color/white"
android:clickable="true"

Fragment背景默认是透明的,所以我们能看到两个Fragment重叠在一起。当我们为每个Fragment添加背景之后,即使两个Fragment叠加在一起,我们也只看到一个。至于为什么要设置clickable=”true”,是因为两个Fragment叠加在一起,虽然我们只能看到上面那个,但是下面那个仍然能接收到事件。设置clickable=”true”时,上面的Fragment会拦截掉所有事件。 
这样处理,能从视觉上解决问题,但是Activity异常销毁时,同一个Fragment同时出现两个实例的客观事实没有改变。有时你会发现Fragment中的某个网络接口明明应该只调用一次,Log却打印调用两次,其实是Fragment创建了两个实例。

2.3、在初始化添加fragment时,先清除当前Activity已有的fragment(推荐)

/*
封装的方法
*/
private void destroyFragment() {
        @SuppressLint("RestrictedApi")
        List<Fragment> fragmentList = getSupportFragmentManager().getFragments();
        if (fragmentList != null) {
            for (int i = 0; i < fragmentList.size(); i++) {
                getSupportFragmentManager().beginTransaction().remove(fragmentList.get(i)).commitAllowingStateLoss();
            }
        }

    }

推荐第三种方法,因为Activity已经被回收了,强行保留fragment数据可能出现bug,重新初始化重新加载确保万无一失

非常感谢ChenSuYu_转载的文章:https://blog.csdn.net/chenduyu/article/details/69243393

猜你喜欢

转载自blog.csdn.net/Hunter2916/article/details/84405080