250

假设我有一个以编程方式添加片段的活动:

private void animateToFragment(Fragment newFragment, String tag) {
    FragmentTransaction ft = getFragmentManager().beginTransaction();
    ft.replace(R.id.fragment_container, newFragment, tag);
    ft.addToBackStack(null);
    ft.commit();
}

返回上一个可见片段的最佳方法是什么?

我发现在 Android 中单击按钮时触发后退按钮功能,但我认为模拟后退键事件不是正确的方法(我也无法让它工作):

dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_BACK));

调用finish()只是关闭我不感兴趣的活动。

有没有更好的方法来解决这个问题?

4

14 回答 14

392

getFragmentManager().popBackStack()方法(有几种可供选择)

http://developer.android.com/reference/android/app/FragmentManager.html#popBackStack()

于 2012-06-02T15:49:30.273 回答
137

为了详细说明提供的其他答案,这是我的解决方案(放置在活动中):

@Override
public void onBackPressed(){
    FragmentManager fm = getFragmentManager();
    if (fm.getBackStackEntryCount() > 0) {
        Log.i("MainActivity", "popping backstack");
        fm.popBackStack();
    } else {
        Log.i("MainActivity", "nothing on backstack, calling super");
        super.onBackPressed();  
    }
}
于 2013-06-28T16:24:33.993 回答
37

当我们更新/添加片段时,

应包括.addToBackStack().

getSupportFragmentManager().beginTransaction()
    .add(detailFragment, "detail") // Add this transaction to the back stack (name is an optional name for this back stack state, or null).
    .addToBackStack(null)
    .commit();

之后,如果getFragments.popBackStackImmediate()我们添加/更新片段,则返回 true,然后返回当前屏幕。

于 2013-07-13T10:52:31.760 回答
18

Android 导航架构组件。

以下代码适用于我:

findNavController().popBackStack()
于 2020-09-30T06:49:29.697 回答
14

如果我没有将 addToBackStack() 添加到我的片段事务中,这些答案将不起作用,但是您可以使用:

getActivity().onBackPressed();

从你的任何一个片段往后退一步;

于 2019-10-02T02:26:59.830 回答
10

将这些行添加到您的 onBackPressed() 方法中。popBackStackImmediate() 方法会让你回到前一个片段,如果你在后栈上有任何片段`

if(getFragmentManager().getBackStackEntryCount() > 0){
     getFragmentManager().popBackStackImmediate();
}
else{
    super.onBackPressed();
}

`

于 2017-03-23T10:23:47.537 回答
5

当您想要在主片段中按下时关闭应用程序时,此解决方案非常适用于基于底部栏的片段导航。

另一方面,当您打开在我的代码中定义为“DetailedPizza”的辅助片段(片段中的片段)时,它将返回主片段的先前状态。干杯!

背面的内部活动放了这个:

Fragment home = getSupportFragmentManager().findFragmentByTag("DetailedPizza");

if (home instanceof FragmentDetailedPizza && home.isVisible()) {
    if (getFragmentManager().getBackStackEntryCount() != 0) {
        getFragmentManager().popBackStack();
    } else {
        super.onBackPressed();
    }
} else {
    //Primary fragment
    moveTaskToBack(true);
}

并像这样启动另一个片段:

Fragment someFragment = new FragmentDetailedPizza();
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.replace(R.id.container_body, someFragment, "DetailedPizza");
transaction.addToBackStack("DetailedPizza");
transaction.commit();
于 2017-11-14T13:52:41.617 回答
3

科特林答案

  1. 首先,调用Fragment Manager
  2. 之后,使用onBackPressed() 方法。

使用 Kotlin 在 Android Studio 4.0 中编码:

fragmentManager?.popBackStack()
于 2020-07-16T14:20:46.140 回答
2

使用以下代码以编程方式返回上一个片段。

if ( getFragmentManager().getBackStackEntryCount() > 0) 
{
          getFragmentManager().popBackStack();
          return;
}
super.onBackPressed();
于 2016-01-23T13:06:10.043 回答
2

要使该片段再次出现,只需将该片段添加到您想要返回的 backstack 中,例如:

button.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        Fragment fragment = new LoginFragment();
        //replacing the fragment
        if (fragment != null) {
            FragmentTransaction ft = ((FragmentActivity)getContext()).getSupportFragmentManager().beginTransaction();
            ft.replace(R.id.content_frame, fragment);
            ft.addToBackStack("SignupFragment");
            ft.commit();
        }
    }
});

在上述情况下,我在按下时打开LoginFragmentButton button现在用户在SignupFragment. 所以如果addToBackStack(TAG)调用了 where TAG = "SignupFragment",那么当按下后退按钮时LoginFragment,我们会回到SignUpFragment

快乐编码!

于 2018-01-25T12:07:32.140 回答
2

通过添加fragment_tran.addToBackStack(null)最后一个片段,我可以返回最后一个片段。

添加新片段

view.findViewById(R.id.changepass).setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            FragmentTransaction transaction = getActivity().getSupportFragmentManager().beginTransaction();
            transaction.replace(R.id.container, new ChangePassword());
            transaction.addToBackStack(null);
            transaction.commit();
        }
    });
于 2019-02-20T11:12:20.573 回答
1

我来到这里寻找或相同的想法,同时我想出了自己的想法,我相信这还不错,如果与 ViewPager 一起使用。

所以我所做的是重写包含 viewPager 的父活动中的 onBackPressed 方法,并将其设置为始终返回负 1 位置,直到它到达第一个片段,然后关闭活动。

@Override
public void onBackPressed() {
    if(viewPager.getCurrentItem()>0){
        viewPager.setCurrentItem(viewPager.getCurrentItem()-1);
    } else {
        super.onBackPressed();
        this.close();
    }
}

private void close(){
    this.finish();
}

这可能有一个缺点,就像它每次只返回一个方向,所以如果有标签并且你切换位置并跳过片段,它可能不会很好用,(从 0 到 2,然后按回会让你1,而不是 0)

对于我的情况,viewPager 中有 2 个片段没有标签,它可以很好地完成工作。

于 2020-03-07T00:30:17.743 回答
1

遵循对我有用的Kotlin代码

1.在使用多个片段的简单活动类中添加

override fun onBackPressed() {
    if (supportFragmentManager.backStackEntryCount > 0) {
        Log.i(TAG, "=============onBackPressed - Popping backstack====")
        supportFragmentManager.popBackStack()
    } else {
        Log.i(TAG, "=============onBackPressed called because nothing on backstack====")
        super.onBackPressed()
    }
}

2.在BottomNavigationView Activity类中添加了多个片段

override fun onBackPressed() {

    Log.e(TAG, "=============onBackPressed")
    val navController = findNavController(R.id.nav_host_fragment)
    when (navController.currentDestination!!.id) {
        R.id.navigation_comments, R.id.navigation_my_posts -> {
            menuItemPosition = 0
            navController.navigate(R.id.navigation_home)
            Log.i(TAG, "=============onBackPressed - Popping backstack with First fragment ====")
        }
        else -> {
            Log.i(TAG, "=============onBackPressed called because nothing on backstack====")
            super.onBackPressed()
        }
    }
}
于 2021-07-22T10:45:00.977 回答
0

试试下面的代码:

@Override
    public void onBackPressed() {
        Fragment myFragment = getSupportFragmentManager().findFragmentById(R.id.container);
        if (myFragment != null && myFragment instanceof StepOneFragment) {
            finish();
        } else {
            if (getSupportFragmentManager().getBackStackEntryCount() > 0) {
                getSupportFragmentManager().popBackStack();
            } else {
                super.onBackPressed();
            }
        }
    }
于 2019-07-25T09:45:19.907 回答