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

时间:2013-01-11 09:57:37

标签: android fragment back

我的应用中只有一个activity和多个fragments

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

Fragment A1 called from A

B1 called from B

B2 called from B1

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

因此,当我按下fragment A1 的后退按钮时,它应该返回 A ,类似于 B2 被按下, B1 出现,从 B1 B ,依此类推。

如何实现此类功能?

10 个答案:

答案 0 :(得分:31)

public void onBackPressed()
{
    FragmentManager fm = getActivity().getSupportFragmentManager();
    fm.popBackStack();
}

答案 1 :(得分:23)

我刚刚实施了类似的场景。

活动'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替换现有片段:

@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();
    }
}

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

答案 2 :(得分:16)

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

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

当backstack中只有一个片段时,我们基本上告诉android将整个应用程序移回。

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

因此,在对此进行更多阅读之后,我发现你可以add fragment manager transactions to back stack然后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. 如果活动是任务后堆栈中的唯一活动,则在后台推送任务。
  3. 在我的情况下,它是后者,所以我修改了我之前的答案中被覆盖的onBackPressed方法,如下所示

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

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

答案 3 :(得分:5)

Just Do

getActivity().getFragmentManager().popBackStack();

答案 4 :(得分:4)

您必须按照here.

所述实现自己的backstack实现

每当您点击片段中的后退按钮时,您都可以调用popFragments(),并在从一个片段导航到其他片段时调用pushFragments()

答案 5 :(得分: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);

        }
    }
}

答案 6 :(得分:0)

后退按钮将按顺序遍历,其中片段为added to backstack。默认情况下,这是作为导航功能提供的。现在,如果你想去特定的片段,你可以从后台进行show it

答案 7 :(得分:0)

您可以通过在backStack中添加标记来处理它。在这里查看我的答案:

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

希望有所帮助

答案 8 :(得分:-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;
        }
    });
}

//快乐编码

答案 9 :(得分:-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();

                }
            });

它适用于我。