Activity + Fragment 页面重叠问题

2,445 阅读2分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

Activity + Fragment 页面重叠问题

今天在遇到一个很奇怪的问题,我们的软件是用Activity + Fragment构成,在某些场景下,居然发现了有Fragment重叠的现象,究其本质,是因为原来未被销毁,而又新建了一个Fragment,那么这种情况怎么避免呢。

一、 造成问题的原因

根本原因:Activity被销毁并重新创建了,但已经加载过的Fragmen被保存了下来,这时Activity重新创建时又产生了新的Fragment,所以重叠了。

问题场景:

  1. 横竖屏切换

  2. 报错之后恢复页面

  3. 内存不足时Activity销毁

深入探究为什么横竖屏后会产生这个现象呢?

我在网上找到赞同的解释:

当我们旋转屏幕的时候,activity会被销毁并重新创建,并且在销毁之前执行了onSaveInstanceState(Bundle outState)这个方法。这个方法会保存activity的一些信息,其中就包括添加过的fragment,当activity被重新创建时,会初始化其中的变量,这个时候点击底部导航的话会重新去添加fragment,也就导致了重叠的问题。

二、 解决方法

为了模拟这一场景,可在手机 开发者选项-> 应用->不保留活动 模拟场景。

解决方式一:

在Activity回收时不保存状态,这样当Activity销毁时再进入时,就重新加载视图


@Override

protected void onSaveInstanceState(Bundle outState) {

// super.onSaveInstanceState(outState);

}

解决方式二:

  1. 新建Fragment的集合,初始化时加载Fragment

  2. 在显示Fragment时,为每一个Fragment添加一个tag

  3. 后在ActivityonCreate中从Bundle中取出,并在集合中替换相应的Fragment

  4. 显示Fragment时将其它的隐藏

  5. 如果想记录保存前的Fragment索引


private void showFragment(int position) {

mCurrentFragPosition = position;

}


@Override

protected void onSaveInstanceState(Bundle outState) {

super.onSaveInstanceState(outState);

outState.putInt("position", mCurrentFragPosition);

}


@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

if (savedInstanceState != null) {

mCurrentFragPosition = savedInstanceState.getInt("position");// 恢复崩溃之前fragment所对应的position

Fragment fragment = mFragmentManager.findFragmentByTag("" + mCurrentFragPosition);

if (fragment != null)

mFragments[mCurrentFragPosition] = fragment;

}

}