【问题标题】:Avoid adding the same fragment several times to backStack避免多次将相同的片段添加到 backStack
【发布时间】:2019-07-22 09:22:35
【问题描述】:

我有一个包含 4 个片段的活动。我想避免用户在退出前点击 100 次的情况。当一个片段被设置时,它被添加到后台堆栈。 例如:用户按以下顺序设置片段:1、2、3、4 然后他设置片段 2 和 4。我的 backStack 看起来像这样(片段 4 可见):2、4、3、2、1 并退出。 我希望我的 backStack 看起来像:2、3、1 并退出。

我已经尝试使用 popBackStackImmediate(string, int flags) 解决我的问题,就像在这篇文章中一样: Prevent The Same Fragment From Stacking More Than Once ( addToBackStack) 但我的 backStack 看起来像(有 4 个可见)2、1 并退出。 我推断 popBackStackImmediate() 正在删除弹出堆栈顶部的堆栈(我希望你知道我的意思)。

private void setFragment(Fragment fragment) {

        String backStateName = fragment.getClass().getName();

        FragmentManager manager = getSupportFragmentManager();
        boolean fragmentPopped = manager.popBackStackImmediate (backStateName, 0);

        if (!fragmentPopped){ //fragment not in back stack, create it.
            FragmentTransaction ft = manager.beginTransaction();
            ft.replace(R.id.main_frame, fragment);
            ft.addToBackStack(backStateName);
            mMainNav.setItemBackgroundResource(R.color.PopWindowBorder_HomeRenovationfragment);
            ft.commit();
        }
    }

我希望每个片段在后台堆栈中不超过一次,而不会破坏后台堆栈的顺序,以便拥有一个看起来像这样的后台堆栈:2、3、1 并退出。 :)

【问题讨论】:

  • 您是否考虑过阻止用户多次实际添加片段?这对我来说听起来更自然。
  • 您是否考虑过使用带有片段适配器的视图分页器?
  • @a_local_nobody 这对我来说听起来也不错。但这是不可能的,如果你阻止他添加第二次,它就不会做正确的事情。实际上,我需要删除旧堆栈并且 popBackStack 工作得很好,但是抑制了其他堆栈......当阻止他时,我将获得这个后堆栈(片段 4 可见):4、3、2、1 并退出。我认为它会抛出一个异常,但无论如何,我不希望这个结果:)
  • @a_local_nobody 什么是带有片段适配器的 viewPager(对不起,我是初学者 ^^)。你有可以启发我的链接吗?
  • 没问题,当你想在不同的片段之间导航时,通常使用带有片段适配器的视图页面,看看这个:developer.android.com/training/animation/screen-slide。注意刷卡部分只是福利的一部分

标签: android android-fragments back-stack fragmenttransaction fragment-backstack


【解决方案1】:

请找到下面的代码,因为它可以帮助你,我也可以在评论部分添加它,但我的声誉不足以添加 cmets

 private fun loadFragment(fragment: Fragment, previousFragment: Fragment?) {

    val transaction = supportFragmentManager.beginTransaction()
 if (supportFragmentManager.findFragmentByTag(fragment::class.java.simpleName) != null) {
        if (previousFragment != null) {
            transaction.hide(previousFragment).show(fragment).commit()
        } else {
            transaction.show(fragment).commit()
        }
    } else {

        if (previousFragment != null) {
            transaction.hide(previousFragment).add(R.id.frame_container, fragment, fragment::class.java.simpleName).addToBackStack(null).commit()
        } else {
            transaction.add(R.id.frame_container, fragment, fragment::class.java.simpleName).addToBackStack(null).commit()
         }
    }
    this@BaseActivity.previousFragment = fragment
  }

【讨论】:

  • 嗨,感谢您的回答,但它不会删除 backStack 中的片段 ^^。还是谢谢你
  • 或者我没看懂你的代码,因为它是用 Kotlin 写的,我不懂这种语言 ^^。
  • 嘿@mathislr,在上面的代码中,如果片段不存在于后堆栈中,我们只会添加片段,否则我们将隐藏前一个片段并显示当前片段,它已经过测试并且工作代码,我在很多项目中都使用过,如果有任何问题,请在评论部分提出,我一定会尽快解决问题。
  • 这段代码是用kotlin写的,不是吗?因为我不知道 val 和 fun 是什么......我个人在 java 中编码,无论如何谢谢你给我时间:)
猜你喜欢
  • 2016-11-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-25
  • 1970-01-01
  • 1970-01-01
  • 2020-07-30
相关资源
最近更新 更多