【问题标题】:popBackStackImmediate not showing fragment when the current fragment transaction is not added in the backstackpopBackStackImmediate 在当前分片事务未添加到后台堆栈时不显示分片
【发布时间】:2017-07-24 10:42:38
【问题描述】:

当序列中的所有片段都添加到后台堆栈时,Popbackstack 工作正常,但当其中一个事务未添加到后台堆栈时,Popbackstack 工作正常。

这是我的导航:

1.替换片段以加载主页片段。此事务未添加到后台堆栈。

  1. 替换片段以加载登录片段。此事务已添加到 backstack。

    3.替换片段以加载登录片段。此事务未添加到 backstack。

    现在,当我按下后退按钮时,什么也没发生。而理想情况下,它应该从登录片段转到主片段。 这是我在主要活动中的 onbackpressed 方法:

    @Override
    public void onBackPressed() {
        if(getSupportFragmentManager().getBackStackEntryCount()>0)
        {
            FragmentManager.BackStackEntry backStackEntry = getSupportFragmentManager().getBackStackEntryAt(getSupportFragmentManager().getBackStackEntryCount() - 1);
            String str = backStackEntry.getName();
            FragmentManager fm=getSupportFragmentManager();
            //getSupportFragmentManager().popBackStackImmediate();
            fm.popBackStack(str, FragmentManager.POP_BACK_STACK_INCLUSIVE);
        }
        else {
            super.onBackPressed();
        }
    
    
    }
    

【问题讨论】:

  • 我认为它有效。只是您显示了两个片段(您的 LoggedInFragment 和您的 HomeFragment)。由于 LoggedInFragment 已显示在 HomeFragment 之后,因此 HomeFragment 不可见,因为 LoggedInFragment 将其隐藏。您不能指望 LoggedInFragment 在您按下返回时消失,因为事务不在后台堆栈中。
  • 所以要解决您的问题,一种解决方案可能是测试当前 Fragment 是否为 LoggedInFragment。如果是这种情况,您从容器中删除片段,然后弹出返回堆栈以返回主页。
  • 哇,你是绝对正确的,非常感谢。
  • 但是请不要评论,而是写在答案中,这样我们都可以得分。
  • 我上面的解决方案有点乱。另一个应该是将事务添加到 bs,然后当用户按下时测试它是否是 LoggedInFragment,然后弹出 bs 直到 homeFragment

标签: android android-fragments android-fragmentactivity fragment-backstack fragmentmanager


【解决方案1】:

popBackstack 仅“弹出”后台堆栈中的内容。 由于您在按下返回时将 LoginFragment 替换为 LoggedInFragment 时尚未添加事务:

  • Lo​​ggedInFragment 仍然存在,
  • Lo​​gInFragment 被弹出
  • 显示 HomeFragment

但是因为 LoggedInFragment 是在 HomeFragment 之后添加的,所以 HomeFragment 会显示在它的下方。所以你看不到它被 LoggedInFragment 隐藏了。

一种解决方案是在将 LogInFragment 替换为 LoggedInFragment 时将事务添加到后台堆栈。 然后在onBackPressed 中测试当前片段是否为 LoggedInFragment。如果是这种情况,您将返回堆栈弹出到 HomeFragment (不包括在内)。这样 LoggedInFragment 和 LogInFragment 都会弹出。

编辑

@Override
public void onBackPressed() {
    FragmentManager manager = getSupportFragmentManager();
    Fragment fragment = manager.findFragmentById(R.id.my_fragment_container);
    // If there is something in the back stack AND the current fragment is the LoggedInFragment
    if (manager.getBackStackEntryCount() > 0
            && fragment instanceof LoggedInFragment) {            
        manager.popBackStack(HomeFragment.class.getSimpleName(), 0);
    } else {
        super.onBackPressed();
    }
}

为了按名称检索 HomeFragment,您需要在将当前 Fragment 替换为 HomeFragment 时标记您的事务。通常我用片段的类简单名称标记所有事务,这样我就可以重试任何片段:

transaction.replace(R.id.my_fragment_container, fragment, fragment.getClass().getSimpleName());

【讨论】:

    【解决方案2】:

    Eselfar 对问题的解释是正确的,但他提供的代码对我来说不够通用。

    我(希望)在一般情况下通过以下代码解决了这个问题:

    @Override
    public void onBackPressed() {
        Fragment currentFragment = getCurrentFragment();
    
        if (mFragmentManager.getBackStackEntryCount() > 0) {
    
            // In a normal world, just popping back stack would be sufficient, but since android
            // is not normal, a call to popBackStack can leave the popped fragment on screen.
            // Therefore, we start with manual removal of the current fragment.
            removeCurrentFragment();
    
            mFragmentManager.popBackStack();
        } else {
            super.onBackPressed();
        }
    }
    
    private Fragment getCurrentFragment() {
        return mFragmentManager.findFragmentById(getContentFrameId());
    }
    
    private void removeCurrentFragment() {
        FragmentTransaction ft = mFragmentManager.beginTransaction();
        ft.remove(getCurrentFragment());
        ft.commit();
    
        // not sure it is needed; will keep it as a reminder to myself if there will be problems
        // mFragmentManager.executePendingTransactions();
    }
    

    【讨论】:

    • 您的navigateUp() 何时被调用?要将 onBackPressed 与 Fragments 一起使用,您的 Activity 需要实现 FragmentActivity
    • navigateUp() 在用户单击工具栏中的“向上”按钮时被调用。
    • 您仍然可以在您的方法中手动调用onBackPressed()。如果您不想要像 OP 一样的特定行为,您甚至不需要覆盖 onBackPressed 本身。如果您使用 Fragments,请确保您的 Activity 扩展了 FragmentActivity
    • 上导航和后导航不一样。例如。当用户通过非登陆屏幕上的通知进入应用程序时,向上导航应该让他/她留在应用程序中,而返回导航应该让他/她回到他/她来自的地方。
    • 是的,你是对的。那么您的问题与 OP 问题有什么关系,因为您似乎有不同的问题?基本上,当您的案例与“向上”有关时,OP 会尝试管理“返回”按钮。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-07
    • 1970-01-01
    • 1970-01-01
    • 2015-09-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多