如何在按下单个片段的手动后退按钮时返回上一个片段?

Mih*_*hah 27 android back fragment

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

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

Fragment A1 called from A

B1 called from B

B2 called from B1
Run Code Online (Sandbox Code Playgroud)

所有fragments都有单独的后退按钮.

因此,当我按下fragment A1的后退按钮时,它应该返回到A,同样当按下B2的后退按钮时,B1出现,从B1B,依此类推.

如何实现这种功能?

Man*_*oba 35

public void onBackPressed()
{
    FragmentManager fm = getActivity().getSupportFragmentManager();
    fm.popBackStack();
}
Run Code Online (Sandbox Code Playgroud)

  • 如果使用import android.support.v4.app.FragmentManager,最佳答案; (2认同)

小智 24

我刚刚实现了类似的场景.

活动'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();
    }
}
Run Code Online (Sandbox Code Playgroud)

片段:'A1'

当菜单项单击操作发生时,我用新的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);
}
Run Code Online (Sandbox Code Playgroud)

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

由于所有片段都有一个父Activity(即'A'),onBackPressed()方法允许您弹出片段(如果有片段)或只返回上一个Activity.

@Override
public void onBackPressed() {
    if(getFragmentManager().getBackStackEntryCount() == 0) {
        super.onBackPressed();
    }
    else {
        getFragmentManager().popBackStack();
    }
}
Run Code Online (Sandbox Code Playgroud)

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


Suh*_*has 16

@ trueblue的回答让我得到了一个小问题,但是很烦人的问题.当背靠背上只有一个片段并按下后退按钮时,该框架将被移除,应用程序将保持活动状态并显示空白屏幕.用户需要再次按下后退按钮才能退出应用程序.我将原始代码修改为以下内容以处理这种情况

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

当backstack中只有一个片段时,我们基本上告诉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);
Run Code Online (Sandbox Code Playgroud)

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

  1. 从正在运行活动的任务的后堆栈中删除容纳该片段的活动.这是因为您不希望以空白活动结束
  2. 如果活动是任务后堆栈中的唯一活动,则在后台推送任务.

在我的情况下,它是后者,所以我修改了onBackPressed我之前的答案中的重写方法,如下所示

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

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


TNR*_*TNR 5

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

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


小智 5

做就是了

getActivity().getFragmentManager().popBackStack();
Run Code Online (Sandbox Code Playgroud)


S.D*_*.D. 0

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