如何使用Backstack进行交易

时间:2016-01-24 19:58:27

标签: android android-fragments

在我的应用中,我有一个带3个项目的导航抽屉。当我点击某个项目时,它会加载并替换实际的片段。片段A应始终保存到后台堆栈,因此当我单击“后退”时,应将A放置在具有先前保存状态的屏幕上。此外,当我单击导航抽屉中的A时,应该出现具有已保存状态的后堆栈中的相同A.

我试图调用onBackPressed,因为它应该完全按照我的需要执行操作,只需从后端堆栈加载以前保存的片段状态。但是当我按下Back或在NavDrawer中单击A时,没有任何反应。

我的代码

public void changeFragment(int position) {
    fragTransaction = fragManager.beginTransaction();

    switch(position) {
        // Main fragment; his previous state should be always in back stack
        case 0:
            appBar.setTitle(leftMenuTitles[position]);
            onBackPressed();
            break;
        // Doesn't matter if state is lost
        case 1:
            appBar.setTitle(leftMenuTitles[position]);
            fragTransaction.replace(R.id.fragment_holder, fragmentDatabase)
                    .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
                    .commit();
            break;
        // Doesn't matter if state is lost
        case 2:
            appBar.setTitle(leftMenuTitles[position]);
            fragTransaction.replace(R.id.fragment_holder, fragmentSettings)
                    .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
                    .commit();
            break;
        // When no fragment found, make me some delicious toast
        default:
            Toast.makeText(this, "No such position in NavDraw " + position, Toast.LENGTH_LONG).show();
    }



    // Close NavigationDrawer

    drawerLayout.closeDrawer(leftLinearLayoutNavDrawer);
}

如果有人为我解释,我会非常感激。我从我读过的内容中了解到,当我调用addToBackStack()时,它会保存事务,而不是那个域。而且我无法在不调用onBackPressed()的情况下找到如何从后端堆栈加载片段。我在这里阅读了android开发者网站以及很多问题,但我仍然无法弄清楚片段交易的工作原理。

1 个答案:

答案 0 :(得分:1)

您的假设是正确的,addToBackStack()保存整个事务 - 也就是说,它保存您在FragmentTransaction上执行的任何撤消操作。这也意味着,如果在事务中执行replace(),则弹出后栈时将恢复上一个片段。

要返回后台堆栈,请调用get(Support)FragmentManager().popBackStackImmediate();,它会撤消添加到后台堆栈的最后一个事务的更改。

在任何情况下,你都不应该自己调用onBackPressed()回调,这通常由android系统调用。

我会尝试通过代码向您解释。在onCreate()中,添加第一个片段:

fragManager.beginTransaction();
    .replace(R.id.fragment_holder, fragmentMain)
    .commit();

然后,当按下导航抽屉菜单项时,替换片段并添加到后面的堆栈(按下后退时将取消替换)。

public void changeFragment(int position) {
    fragTransaction = fragManager.beginTransaction();

    switch(position) {
        // Main fragment; his previous state should be always in back stack
        case 0:
            appBar.setTitle(leftMenuTitles[position]);
            fragTransaction.replace(R.id.fragment_holder, fragmentMain)
                    .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
                    .addToBackStack(null)
                    .commit();
            break;
        // Doesn't matter if state is lost
        case 1:
            appBar.setTitle(leftMenuTitles[position]);
            fragTransaction.replace(R.id.fragment_holder, fragmentDatabase)
                    .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
                    .addToBackStack(null)
                    .commit();
            break;
        // Doesn't matter if state is lost
        case 2:
            appBar.setTitle(leftMenuTitles[position]);
            fragTransaction.replace(R.id.fragment_holder, fragmentSettings)
                    .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
                    .addToBackStack(null)
                    .commit();
            break;
        // When no fragment found, make me some delicious toast
        default:
            Toast.makeText(this, "No such position in NavDraw " + position, Toast.LENGTH_LONG).show();
    }

    // Close NavigationDrawer

    drawerLayout.closeDrawer(leftLinearLayoutNavDrawer);
}

但是,我不确定这是不是你想要的。最好不要使用后台堆栈进行导航抽屉菜单项选择启动的片段事务。