29

我的申请中只有一个activity和多个fragments

两个主要片段 A(左)和 B(右)。

Fragment A1 called from A

B1 called from B

B2 called from B1

都有fragments单独的后退按钮。

因此,当我按下fragment A1的后退按钮时,它应该返回到A,同样,当按下B2的后退按钮时,会出现B1并从B1B等等。

如何实现这种类型的功能?

4

10 回答 10

41
public void onBackPressed()
{
    FragmentManager fm = getActivity().getSupportFragmentManager();
    fm.popBackStack();
}
于 2013-01-11T10:10:13.793 回答
27

我刚才已经实现了类似的场景。

活动'A'->调用片段'A1'并单击菜单项,它调用片段'A2',如果用户从'A2'按下返回按钮,则返回到'A1',如果用户按下之后从“A1”返回,它完成活动“A”并返回。

请参阅以下代码:

活动 'A' - OnCreate() 方法:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activityA);

    if (savedInstanceState == null) {
        Fragment fragInstance;

        //Calling the Fragment newInstance Static method
        fragInstance = FragmentA1.newInstance();

        getFragmentManager().beginTransaction()
                .add(R.id.container, fragInstance)
                .commit();
    }
}

片段:'A1'

当菜单项单击操作发生时,我正在用新的 Fragment 替换现有的 Fragment:

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    if (item.getItemId() == R.id.action_edit_columns) {
        //Open the Fragment A2 and add this to backstack
        Fragment fragment = FragmentA2.newInstance();
        this.getFragmentManager().beginTransaction()
                .replace(R.id.container, fragment)
                .addToBackStack(null)
                .commit();

        return true;
    }
    return super.onOptionsItemSelected(item);
}

活动 'A' - onBackPressed() 方法:

由于所有片段都有一个父 Activity(即“A”),因此 onBackPressed() 方法允许您弹出片段(如果有的话)或返回到前一个 Activity。

@Override
public void onBackPressed() {
    if(getFragmentManager().getBackStackEntryCount() == 0) {
        super.onBackPressed();
    }
    else {
        getFragmentManager().popBackStack();
    }
}

如果您正在寻找在 Fragments 中嵌入 Fragments,请参考链接:http: //developer.android.com/about/versions/android-4.2.html#NestedFragments

于 2015-02-25T02:22:18.327 回答
17

@trueblue 的回答让我解决了一个小而烦人的问题。当 backstack 上只有一个 Fragment 并且您按下返回按钮时,该帧将被删除,并且应用程序保持活动状态并显示空白屏幕。用户需要再按一次返回按钮才能退出应用程序。为了处理这种情况,我将原始代码修改为以下

@Override
public void onBackPressed() {
    if(getFragmentManager().getBackStackEntryCount() == 0) {
        super.onBackPressed();
    }
    else if(getFragmentManager().getBackStackEntryCount() == 1) {
        moveTaskToBack(false);
    }
    else {
        getFragmentManager().popBackStack();
    }
}

当 backstack 中只有 1 个片段时,我们基本上是在告诉 android 将整个应用程序移到后面。

更新(可能是更好的答案)

因此,在对此进行了更多阅读之后,我发现您可以将片段管理器事务添加到后堆栈,然后 android 会自动以所需的方式处理后按。下面的代码片段显示了如何做到这一点

Fragment fragment; //Create and instance of your fragment class here
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();

fragmentTransaction.replace(R.id.fragment_container, fragment).addToBackStack(null);
fragmentTransaction.commit();
fragmentTransaction.addToBackStack(null);

最后一行显示了如何将事务添加到后台堆栈。这解决了大多数情况下片段的后压问题,除了一个。如果您继续按返回按钮,那么最终您将到达一个点,即返回堆栈中只有一个片段。此时,您将要做以下两件事之一

  1. 从正在运行活动的任务的后台堆栈中删除包含该片段的活动。这是因为您不想以空白活动结束
  2. 如果该活动是该任务的后台堆栈中的唯一活动,则将该任务推入后台。

就我而言,是后者,所以我修改了onBackPressed之前答案中的覆盖方法,如下所示

@Override
public void onBackPressed() {
    if(getFragmentManager().getBackStackEntryCount() == 1) {
        moveTaskToBack(false);
    }
    else {
        super.onBackPressed();
    }
}

这段代码更简单,因为它的逻辑更少,而且它依赖于框架而不是我们的自定义代码。不幸的是,我没有设法为第一种情况实现代码,因为我不需要。

于 2016-06-25T17:11:50.233 回答
5

您必须按照此处的说明实现自己的 backstack 实现

您可以popFragments()在单击片段中的后退按钮时调用 ,并pushFragments()在从一个片段导航到另一个片段时调用。

于 2013-01-11T10:06:58.847 回答
5

做就是了

getActivity().getFragmentManager().popBackStack();
于 2015-10-02T05:52:32.237 回答
1

试试这个,它对我有用。

public void onBackPressed() {
    if (mainLayout.isMenuShown()) {
        mainLayout.toggleMenu();
    } else {
        FragmentManager fm = getSupportFragmentManager();
        Log.print("back stack entry", fm.getBackStackEntryCount() + "");

        if (fm.getBackStackEntryCount() > 1) {
            fm.popBackStack();
            // super.onBackPressed();
            // return;
        } else {
            if (doubleBackToExitPressedOnce) {
                fm.popBackStack();
                super.onBackPressed();
                return;
            }

            this.doubleBackToExitPressedOnce = true;
            Toast.makeText(this, "Press one more time to exit",
                    Toast.LENGTH_SHORT).show();

            new Handler().postDelayed(new Runnable() {

                @Override
                public void run() {

                    doubleBackToExitPressedOnce = false;
                }
            }, 3000);

        }
    }
}
于 2015-05-28T07:04:00.200 回答
0

您可以通过在backStack. 在这里检查我的答案:

https://stackoverflow.com/a/19477957/1572408

希望能帮助到你

于 2014-02-04T06:09:16.570 回答
0

后退按钮将按照 Fragments添加到 backstack的顺序遍历。默认情况下,这是作为导航功能提供的。现在,如果您想转到特定的 Fragment,可以从 backstack中显示它。

于 2013-01-11T10:06:40.897 回答
-1
@Override
public void onResume() {

    super.onResume();

    getView().setFocusableInTouchMode(true);
    getView().requestFocus();
    getView().setOnKeyListener(new View.OnKeyListener() {
        @Override
        public boolean onKey(View v, int keyCode, KeyEvent event) {

            if (event.getAction() == KeyEvent.ACTION_UP && keyCode == KeyEvent.KEYCODE_BACK){

                // replace your fragment here

                return true;

            }

            return false;
        }
    });
}

// 快乐编码

于 2014-11-26T09:00:11.063 回答
-1

如果你按下图像,你必须先像这样创建方法

private void Backpresses() {
    getActivity().getSupportFragmentManager().beginTransaction().replace(R.id.contant_main, new Home()).commit();
}

那么当你按下返回图像时,你必须像这样打电话..

 back.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                   Backpresses();

                }
            });

它对我来说很好。

于 2016-10-05T07:49:00.227 回答