Android:在背面按下返回上一个片段

时间:2014-08-17 15:01:43

标签: android android-fragments back-stack android-navigation

我已经实现了Navigation Drawer,它是Activity的子类。我的应用程序中有很多片段。我的问题在这里

想象一下有3个片段:

Fragment_1:Fragment_2:Fragment_3

当我启动应用程序时,会加载Fragment_1 当我点击Fragment_1上的某些组件时,我已导航到Fragment_2,依此类推..

所以它就像

Fragment_1> Fragment_2> Fragment_3

当我从Fragment_2按回键时,我导航回Fragment_1 但是当我从Fragment_3按下键时,我导航回Fragment_1(而不是Fragment_2)

我想在Back Key press

上的应用程序中输入这样的内容

Fragment_1< Fragment_2< Fragment_3

我使用Fragment,FragmentManager,FragmentTransaction如下:

MyFragment fragment = new MyFragment();
FragmentManager fragmentManager = getFragmentManager();

fragmentManager.beginTransaction().replace(R.id.content_frame, fragment).addToBackStack(null)commit();

我尝试在MainActivity中覆盖onBackPressed():

@Override
public void onBackPressed() {


        getFragmentManager().popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
        int count = getFragmentManager().getBackStackEntryCount();
        if (count == 0)
               super.onBackPressed();
    }

5 个答案:

答案 0 :(得分:35)

将您的Activity#onBackPressed()方法更新为:

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

您的实现不起作用的原因是因为方法FragmentManager#popBackStack()是异步的,并且在调用之后不会发生。

来自文档:

  

此函数是异步的 - 它将请求排入pop,但在应用程序返回其事件循环之前不会执行该操作。

参考:http://developer.android.com/reference/android/app/FragmentManager.html#popBackStack(java.lang.String,%20int)

答案 1 :(得分:3)

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

Separate Back Stack for each tab in Android using Fragments

只要单击片段中的后退按钮,就可以调用popFragments(),只要从一个片段导航到另一个片段,就可以调用pushFragments()。

简而言之,

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

答案 2 :(得分:2)

tric在/** * if there is a fragment and the back stack of this fragment is not empty, * then emulate 'onBackPressed' behaviour, because in default, it is not working. * * @param fm the fragment manager to which we will try to dispatch the back pressed event. * @return {@code true} if the onBackPressed event was consumed by a child fragment, otherwise */ public static boolean dispatchOnBackPressedToFragments(FragmentManager fm) { List<Fragment> fragments = fm.getFragments(); boolean result; if (fragments != null && !fragments.isEmpty()) { for (Fragment frag : fragments) { if (frag != null && frag.isAdded() && frag.getChildFragmentManager() != null) { // go to the next level of child fragments. result = dispatchOnBackPressedToFragments(frag.getChildFragmentManager()); if (result) return true; } } } // if the back stack is not empty then we pop the last transaction. if (fm.getBackStackEntryCount() > 0) { fm.popBackStack(); fm.executePendingTransactions(); return true; } return false; }

这也是我用于嵌套片段的......:

onBackPressed

和我的 if (!FragmentUtils.dispatchOnBackPressedToFragments(fm)) { // if no child fragment consumed the onBackPressed event, // we execute the default behaviour. super.onBackPressed(); }

git reflog

答案 3 :(得分:0)

在主要活动的标签更改中使用此代码清除堆栈。

int count = getFragmentManager().getBackStackEntryCount();
        if(count>0){
            for (int i = 0; i <count; i++) {
                getFragmentManager().popBackStack();
            }
        }

然后在你的主要活动的背面按下

 int count = getFragmentManager().getBackStackEntryCount();

     if (count == 0) {
         super.onbackpressed();
        }
else {
        getFragmentManager().popBackStack();
    }
 }

答案 4 :(得分:0)

以下是我的工作和测试代码,这将对您有所帮助

 private static final int TIME_INTERVAL = 2000;
private long mBackPressed;
 private void applyExit() {
    if (mBackPressed + TIME_INTERVAL > System.currentTimeMillis()) {
        finish();
    } else {
         Toast.makeText(this,"Press Again to exit",Toast.LENGTH_LONG).show();
    }
    mBackPressed = System.currentTimeMillis();
}

@Override
public void onBackPressed() {
    fm = getSupportFragmentManager();
    if (drawer.isDrawerOpen(GravityCompat.START)) {
        drawer.closeDrawer(GravityCompat.START);
    }
    if (fm.getFragments().size() <= 1) {
        applyExit();
    } else {
        for (Fragment frag : fm.getFragments()) {
            if (frag == null) {
                applyExit();
                return;
            }
            if (frag.isVisible()) {
                FragmentManager childFm = frag.getChildFragmentManager();
                if (childFm.getFragments() == null) {
                    super.onBackPressed();
                    return;
                }
                if (childFm.getBackStackEntryCount() > 0) {
                    childFm.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
                    return;
                } else {
                    fm.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
                    return;
                }
            }
        }
    }
}