使用导航抽屉切换时,如何只保留片段的一个实例?

时间:2014-07-26 14:35:53

标签: android android-fragments

我的应用程序以AddressFragment开头。从NavigationDrawer开始(其中包括) new AddressFragment:

getSupportFragmentManager().beginTransaction()
                .replace(R.id.container, new AddressFragment())
                .addToBackStack(null)
                .commit();

但我宁愿回到第一个实例。我怎么能这样做?

或者更一般,我怎样才能知道片段的实例是否已经存在然后开始,如果是,否则创建一个?

4 个答案:

答案 0 :(得分:16)

创建片段时为它设置标签,稍后您可以通过片段管理器找到它并相应地替换/创建。

FragmentManager fManager = getFragmentManager();
FragmentTransaction fTransaction = fManager.beginTransaction();
Fragment fragment = fManager.findFragmentByTag("uniqueTag");

// If fragment doesn't exist yet, create one
if (fragment == null) {
    fTransaction.add(R.id.fragment_list, new ListFrag(), "uniqueTag");
}
else { // re-use the old fragment
    fTransaction.replace(R.id.fragment_list, fragment, "uniqueTag");
}

答案 1 :(得分:6)

第一步:

优化当前代码以允许片段拥有自己的" TAG"

getSupportFragmentManager().beginTransaction()
                .replace(R.id.container, new AddressFragment())
                .addToBackStack(**AddressFragment.class.getName()**)
                .commit();

第二步:

在应用程序流程的某处,您需要确定是否存在片段:

public static boolean isFragmentInBackstack(final FragmentManager fragmentManager, final String fragmentTagName) {
    for (int entry = 0; entry < fragmentManager.getBackStackEntryCount(); entry++) {
        if (fragmentTagName.equals(fragmentManager.getBackStackEntryAt(entry).getName())) {
            return true;
        }
    }
    return false;
}

第三步:

执行片段操作

if (exists) {
    // Fragment exists, go back to that fragment
    //// you can also use POP_BACK_STACK_INCLUSIVE flag, depending on flow
    mFragmentManager.popBackStackImmediate(AddressFragment.class.getName(), 0);

} else {
    // Fragment doesn't exist
    // STEP 1 + additional backstack management
}

答案 2 :(得分:2)

首次使用标记创建片段。

当您想要替换它时,尝试使用标记获取片段,如果它返回null,则创建一个新的

答案 3 :(得分:1)

这是经过测试的答案,希望这对您有所帮助 首先在MainActivity中全局创建这些字段

private static final int TIME_INTERVAL = 2000; 
private long mBackPressed;
private FragmentManager fm;
private FragmentTransaction ft;
private DrawerLayout drawer;

现在onNavigationItemSelected()就像那样实现

    @Override
public boolean onNavigationItemSelected(MenuItem item) {
Fragment fragment = null;
Class fragmentClass = null;
switch (item.getItemId()) {
case R.id.nav_home:
fragmentClass = Fragment.class;//this is MainAvctivty extends AppCompatActivity
break;
case R.id.nav_f1:
fragmentClass = FragmentOne.class;
break;
case R.id.nav_f2:
fragmentClass = FragmentTwo.class;
break;
case R.id.nav_f3:
fragmentClass = FragmentThree.class;
break;
case R.id.nav_f4:
fragmentClass = FragmentFour.class;
break;
case R.id.nav_f5:
fragmentClass = FragmentFive.class;
break;
default:
fragmentClass = Fragment.class;
}
try {
fragment = (Fragment) fragmentClass.newInstance();
} catch (Exception e) {e.printStackTrace();}
//Insert the fragment by replacing any existing fragment
fm = getSupportFragmentManager();
ft = fm.beginTransaction();
ft.replace(R.id.frame_container, fragment);
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
ft.addToBackStack(null);
ft.commit();
item.setChecked(true);
setTitle(item.getTitle());
drawer.closeDrawers();
return true;
}

现在处理onbackpressed如下

@Override
public void onBackPressed() {
if (drawer != null) {
fm = getSupportFragmentManager();
ft = fm.beginTransaction();
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else if (fm.getBackStackEntryCount() > 0) {
fm.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_CLOSE);
ft.commit();
} else if (mBackPressed + TIME_INTERVAL > System.currentTimeMillis()) {
super.onBackPressed();
} else {
Toast.makeText(this,"Press again to exit the app",Toast.LENGTH_SHORT).show();
}
mBackPressed = System.currentTimeMillis();
}
}