【问题标题】:OnBackPress On FragmentOnBackPressed 片段
【发布时间】:2020-12-07 06:23:49
【问题描述】:

我正在开发一个包含五个片段的 android 应用程序,我想要的是打开 fragment 1 并且我将其返回到 Main fragment 和我从片段 5 按下后按一样,它也来到 主片段

当我从 MainFragment 按下 Backpress 时,应用程序应该退出。

我已经通过这个链接Link

我还添加了 Dispatcher,但它不符合我的要求。

就像我总是这样打开每个片段

private fun ShowQRCodeFragment() {
    val newFragment: Fragment = QrCodeScanningFragment()
    val transaction1: FragmentTransaction = supportFragmentManager.beginTransaction()
    transaction1.replace(R.id.frameLayout, newFragment)
    transaction1.addToBackStack(null)
    transaction1.commit()
}

更新交易

  private fun FunctionNewSettings() {
    val newFragment: Fragment = CustomSettingsFragment()
    val transaction1: FragmentTransaction = supportFragmentManager.beginTransaction()
    transaction1.replace(R.id.frameLayout, newFragment)
    transaction1.addToBackStack("namedata")
    fragmentManager.popBackStack()
    transaction1.commit()
}

【问题讨论】:

  • 首先 null 不应该在 addToBackStack 中。其次,如果您想维护 backstack,请在您的 Fragment 中注册 onBackPressedDispatcher ,否则您可以在父活动中管理它,但计算 backstack 条目。
  • 如何在主要活动中按计数器完成此操作
  • 以及如何附加调度员
  • 您可以使用 getSupportFragmentmanager 获取 backstackentrycount,google 一下。你会得到你的解决方案。

标签: android android-studio android-layout kotlin android-fragments


【解决方案1】:

您应该在片段事务时使用addToBackStack()。这将允许您在后按时转到上一个片段。 对于应用退出案例,通过fragment标签检查当前fragment是否为MainFragment,并相应调用fragmentmanager.popBackStack()super.onBackPressed()

【讨论】:

  • 我已经添加了backstack
  • 我已经展示了片段开头并更新了问题
【解决方案2】:

在 MainFragment 中,使用

override fun onAttach(context: Context) {
        super.onAttach(context)
        val callback = object : OnBackPressedCallback(
            true // default to enabled
        ) {
            override fun handleOnBackPressed() {
                requireActivity().finish()
            }
        }
        requireActivity().onBackPressedDispatcher.addCallback(
            this, // LifecycleOwner
            callback
        )
    }

在另一个片段中,使用

override fun onAttach(context: Context) {
        super.onAttach(context)
        val callback = object : OnBackPressedCallback(
            true // default to enabled
        ) {
            override fun handleOnBackPressed() {
                for (i in 0 until (requireActivity() as FragmentActivity).supportFragmentManager.backStackEntryCount) {
            activity.supportFragmentManager.popBackStack()
        }
            }
        }
        requireActivity().onBackPressedDispatcher.addCallback(
            this, // LifecycleOwner
            callback
        )
    }

【讨论】:

    【解决方案3】:

    如果你想回到上一个片段首先使用 addToBackStack()

    如果您想通过使用 onBackPressed from 活动退出应用程序/活动,则在 MainFragment 中使用 getActivity().onBackPressed();

    如果您想从 Fragment 使用完成活动 getActivity().finish();

    您还可以在用户单击返回按钮时替换现有片段 fragmentTransaction.replace(int containerViewId, Fragment fragment, String tag)

    【讨论】:

    • 我已经添加了这个,但是当在主要活动布局上打开片段 2 时,它也支持该活动....我想要的是当我点击片段 2 时它应该回到主要的主要片段活动,当我按回 mainfragment 它退出应用程序
    • 那么你可以尝试用一个新的片段替换现有的片段
    • 但更换可能需要时间
    • 我在 transaction1.addToBackStack(null) 之后添加了 fragmentmanager.popBackStack() 它转到前一个片段,它是片段 2 或 5,但我想要的是它总是转到初始片段跨度>
    • 尝试将一些名称传递给返回堆栈以代替 null
    【解决方案4】:

    解决方案

    在您的活动中覆盖onBackPressed() 方法。

    override fun onBackPressed() {
        val count = supportFragmentManager.backStackEntryCount
        if (count > 1) {
            repeat(count - 1) { supportFragmentManager.popBackStack() }
        } else {
            finish()
        }
    }
    

    【讨论】:

      【解决方案5】:

      如果你只是在切换片段,你不需要搞乱后退按钮的行为,你也不应该需要弹出 backstack。

      backstack 只是一个历史记录,就像浏览器上的后退按钮一样。你从一些初始状态开始,比如一个空的容器布局。在此之前没有历史记录(backstack 上没有任何内容),因此如果您现在回击,它将完全退出 Activity


      如果你开始一个片段事务,你add一个新片段到那个容器,你可以使用addToBackStack在历史中创建一个新的“步骤”。于是就变成了

      empty container -> added fragment
      

      如果你回击,它会后退一步(从堆栈中弹出最近的状态)

      empty container
      

      如果不使用addToBackStack,则更改会替换堆栈顶部的当前状态

      (with addToBackStack)
      empty container -> fragmentA -> fragmentB
      
      (without it)
      empty container -> fragmentB
      

      所以通常当你添加你的第一个片段时你会跳过添加到后台堆栈,因为你不想要空容器的更早一步 - 你想要替换那个状态

      empty container
      (add mainFragment without adding the transaction to the backstack)
      mainFragment
      

      现在当您处于显示mainFragment 的第一个状态时,后退按钮将退出活动


      所以addToBackStack 所做的更改会添加到历史记录中,您可以后退一步完成每个更改。跳过它基本上会改变最后的更改而不是进行新的更改。你可以把它想象成添加到 backstack 会下降一个级别,所以当你回击时,你会回到上一个级别。跳过添加让您保持在同一水平,并且只是改变您正在查看的内容 - 回击仍然可以让您提升一个水平。

      因此,您可以使用它来组织后退按钮所采用的“路径”,方法是向堆栈添加新步骤或更改当前步骤。如果你能写出你想要的堆栈,每次返回按钮都会让你后退一步,你就可以创建它!


      最后一件事 - addToBackStack 采用 String? 参数,该参数通常为空,但您可以为要添加的步骤传入标签。这允许您将 backstack 一直弹出到历史记录中的某个点,这就像浏览器允许您跳转到历史记录中的前一个 site,而不仅仅是最后一个 page

      因此,您可以为事务添加名称,例如“显示子片段”,当您在mainFragment 之上添加您的第一个子片段时,这意味着您可以使用带有该标签的popBackstack 直接跳转到最初的@ 987654337@ 状态,下一次后按退出活动。这比从 backstack 中弹出每个步骤并跟踪您需要执行的步骤更方便 - 您可以在历史记录中跳回到定义的点

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-08-17
        • 1970-01-01
        相关资源
        最近更新 更多