Fragment管理问题

概述

该文档主要描述个人在Android开发中关于Fragment的管理,使用Stack的特性(后进先出原则)来存放Fragment,可以在处理Activity的返回操作时得到充分发挥。

Note:这里主要介绍Fragment添加/替换/移除操作。

添加

直接添加Fragment覆盖原有的界面,这里添加的每个Fragment会使用唯一的tag常量来标记,用于推进到Stack里,便于对指定的Fragment完成后续的替换/移除操作,添加操作使用FragmentTransaction.add(int, Fragment, String)方法。

  1. 初始时添加Fragment到Activity上

    1
    2
    3
    4
    5
    6
    7
    final String tag = "1";
    getSupportFragmentManager()
    .beginTransaction()
    .add(R.id.content, MyFragment.newInstance(tag), tag)
    .commit();
    mTagStack.push(tag);
    }
  2. 添加Fragment到已存在的Fragment上:需要先隐藏已存在的Fragment,再完成添加操作,否则原先存在的Fragment还会显示

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    public void addFragmentToTop(final String oldTag, final String newTag) {
    FragmentManager fm = getSupportFragmentManager();
    Fragment fragment = fm.findFragmentByTag(oldTag);
    FragmentTransaction ft = fm
    .beginTransaction()
    .hide(fragment)
    .add(R.id.content, MyFragment.newInstance(newTag), newTag);
    ft.addToBackStack(newTag);
    ft.commit();
    mTagStack.push(newTag);
    }

替换

用新的Fragment替换当前显示的Fragment,注意这里不会使用FragmentTransaction.replace(int, Fragment, String)方法,因为replace方法会将已有的Fragment全部移除,不能实现我们想要的替换效果。这里是先移除当前显示的Fragment,再将新的Fragment添加进来。注意这里Stack的操作是直接替换栈顶元素。

1
2
3
4
5
6
7
8
9
10
11
public void replace(final String oldTag, final String newTag) {
FragmentManager fm = getSupportFragmentManager();
Fragment oldFragment = fm.findFragmentByTag(oldTag);
FragmentTransaction ft = fm.beginTransaction();
ft.remove(oldFragment)
.add(R.id.content, MyFragment.newInstance(newTag), newTag)
.commit();
mTagStack.set(mTagStack.size() - 1, newTag);
}

移除

直接根据tag移除栈顶的Fragment。先执行remove操作,再判断Stack的元素个数是否大于2,若大于2,表示栈里还存在Fragment,则需要显示下一个Fragment,否则和Activity的正常退出操作一样。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public void remove(String tag) {
FragmentManager fm = getSupportFragmentManager();
Fragment removeFragment = fm.findFragmentByTag(tag);
FragmentTransaction ft = fm.beginTransaction();
ft.remove(removeFragment);
if (mTagStack.size() >= 2) {
Fragment showFragment = fm
.findFragmentByTag(mTagStack.get(mTagStack.size() - 2));
ft.show(showFragment);
}
ft.commit();
fm.popBackStack();
}

Note:Activity的返回操作需要根据FragmentManager.getBackStackEntryCount()方法判断BackStack的个数来执行移除退出Activity操作

1
2
3
4
5
6
7
8
@Override
public void onBackPressed() {
int backStackCount = getSupportFragmentManager().getBackStackEntryCount();
if (backStackCount > 0) {
remove(mTagStack.peek());
} else
super.onBackPressed();
}

参考方案

  1. DEMO参考(下载地址)