Android:返回到上一个片段

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/25350397/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 09:21:59  来源:igfitidea点击:

Android : Return to previous fragment on back press

androidandroid-fragmentsback-stackandroid-navigation

提问by Hvn

I have implemented Navigation Drawer which is a subclass of Activity. I have many fragments in my application. My question goes here

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

Imagine there are 3 fragments :

想象一下有3个片段:

Fragment_1 : Fragment_2 : Fragment_3

片段_1:片段_2:片段_3

When I start my application, Fragment_1 is loaded When I click on some components on Fragment_1, I'm navigated to Fragment_2 and so on..

当我启动我的应用程序时,Fragment_1 被加载当我点击 Fragment_1 上的一些组件时,我被导航到 Fragment_2 等等..

So it's like

所以就像

Fragment_1 > Fragment_2 > Fragment_3

Fragment_1 > Fragment_2 > Fragment_3

When I press back key from Fragment_2, I'm navigated back to Fragment_1 But when I press back key from Fragment_3, I'm navigated back to Fragment_1 (instead of Fragment_2)

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

I want something like this in my application on Back Key press

我想在我的应用程序中按后退键

Fragment_1 < Fragment_2 < Fragment_3

片段_1 < 片段_2 < 片段_3

I have used Fragment, FragmentManager, FragmentTransaction as follows :

我使用 Fragment、FragmentManager、FragmentTransaction 如下:

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

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

and I tried overriding onBackPressed() in my MainActivity :

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

@Override
public void onBackPressed() {


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

回答by Leandro

Update your Activity#onBackPressed()method to:

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

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

The reason your implementation doesn't work is because the method FragmentManager#popBackStack()is asynchronous and does not happen right after it is called.

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

From the documentation:

从文档:

This function is asynchronous -- it enqueues the request to pop, but the action will not be performed until the application returns to its event loop.

这个函数是异步的——它将请求排入队列以弹出,但直到应用程序返回到其事件循环才会执行该操作。

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

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

回答by Sam

You have to implement your own backstack implementation as explained here

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

Separate Back Stack for each tab in Android using Fragments

使用 Fragments 为 Android 中的每个选项卡单独返回堆栈

You can call the popFragments() whenever you click the back button in a fragment and call pushFragments() whenever you navigate from one Fragment to other.

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

in Short,

简而言之,

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

回答by ahmed_khan_89

The tric is in FragmentManager#executePendingTransactions();.

三角函数在FragmentManager#executePendingTransactions();.

This is what I use for nested fragments as well...:

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

/**
 * 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;
}

and in my onBackPressed:

在我的onBackPressed

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

回答by Ness Tyagi

Here is working and tested code by me, This will help you

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

 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;
                }
            }
        }
    }
}

回答by Nanda

Use this code on tab change in your main activity to clear the stack.

在主要活动中的选项卡更改时使用此代码来清除堆栈。

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

Then on Back pressed of your main activity do this

然后在您的主要活动的后退上执行此操作

 int count = getFragmentManager().getBackStackEntryCount();

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