Activity内嵌Fragment,当Activity recreate时Fragment出现重叠

recreate()

Activity recreate()之后会出现fragment重叠的问题,需要给fragment增加tag

@Override
protected void onCreate(Bundle savedInstanceState) {
    // 判断当前是recreate还是新启动
    if (savedInstanceState == null) {
        switchFragment(INDEX_HOMEPAGE);
    }
}

@Override
protected void onSaveInstanceState(@NonNull Bundle outState) {
    super.onSaveInstanceState(outState);
    // recreate时保存当前页面位置
    outState.putInt("index", mLastIndex);
}


@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
    super.onRestoreInstanceState(savedInstanceState);
    // 恢复recreate前的页面
    mLastIndex = savedInstanceState.getInt("index");
    switchFragment(mLastIndex);
}

private void switchFragment(int index) {
    FragmentManager fragmentManager = getSupportFragmentManager();
    FragmentTransaction transaction = fragmentManager.beginTransaction();
    // 将当前显示的fragment和上一个需要隐藏的fragment分别加上tag, 并获取出来
    // 给fragment添加tag,这样可以通过findFragmentByTag找到存在的fragment,不会出现重复添加
    mCurrentFragment = fragmentManager.findFragmentByTag("fragment" + index);
    mLastFragment = fragmentManager.findFragmentByTag("fragment" + mLastIndex);
    // 如果位置不同
    if (index != mLastIndex) {
        if (mLastFragment != null) {
            transaction.hide(mLastFragment);
        }
        if (mCurrentFragment == null) {
            mCurrentFragment = getFragment(index);
            transaction.add(R.id.container, mCurrentFragment, "fragment" + index);
        } else {
            transaction.show(mCurrentFragment);
        }
    }


    // 如果位置相同或者新启动的应用
    if (index == mLastIndex) {
        if (mCurrentFragment == null) {
            mCurrentFragment = getFragment(index);
            transaction.add(R.id.container, mCurrentFragment, "fragment" + index);
        }
    }
    transaction.commit();
    mLastIndex = index;
}
  • 使用上述方法完成后,在应用切到后台一段时间,切回来,会出现crash,下面是解决方案

Android "Unable to instantiate fragment"解决方案

方案一: 给每个fragment增加一个静态的构造方法
// fragment
public static HomeFragment getInstance() {
    HomeFragment fragment = new HomeFragment();
    return fragment;
}

// 调用
fragment = HomeFragment.getInstance();
  • 但是使用上述方法,在内存不够的情况导致应用被回收,再次进入应用,应用重建导致crash
  • 问题原因:
    • Fragment f = (Fragment)clazz.newInstance()引起的,反射创建失败
    • 反射创建失败原因
      • Fragment无空构造方法
      • Fragment是内部类,没有加static
解决方案:在Activity的onCreate()方法中的super.onCreate()中传入null
@Override
protected void onCreate(Bundle savedInstanceState) {
    // 解决Fragment需要一个构造函数的问题
    super.onCreate(null);
    ...
}
发布了175 篇原创文章 · 获赞 56 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/qq_39424143/article/details/104373182