【问题标题】:Handle fragment back navigation and bottom navigation view selected item处理片段返回导航和底部导航视图选定项
【发布时间】:2019-06-11 18:59:33
【问题描述】:

我已经实现了一个bottomNavigationView,每个选项都有它的入口片段,有些在同一个选项下有更多的导航。

有点像这样:

A->A1

B->B1

C->C1->C2

D->D1

E->E1->E2

其中 A、B、C、D 和 E 是底部导航视图的选项(MenuItem),A1、B1、C1、D1、E1 分别是这些选项的条目片段

所需的导航是应用程序的入口和出口点始终是选项 A(入口片段 A1)。因此,如果用户在该选项的条目片段中导航到另一个选项,则任何后退导航的行为都应该是转到选项 A。

我遇到的问题是,bottomNavigationView 始终作为要求存在,因此用户可以随时导航到任何选项。

例如,如果用户导航到选项 E,则在 E1 中执行导航到 E2 的操作,然后导航到选项 B,如果用户按下后退按钮,应用程序应该转到选项 A,因为它位于条目片段 B1 中。 此外,如果用户使用底部导航视图导航到选项 A,然后按后退按钮,因为我们处于退出点,我们应该完成应用程序。

在 OnNavigationItemSelectedListener 中,我使用 beginTransaction.replace 替换所选选项的条目片段的当前片段,对于选项 AI 以外的任何选项添加 addToBackStack(null) 但这本身与所需的导航不匹配,因为如果用户按下后退按钮,导航到选项 A 它导航到上一个选择的选项。 A还尝试在使用@ 987654323替换片段之前尝试弹出背帽子@和replyea添加addToBackStack(BACK_STACK_HOME_TAG)但是在选择第二个选项时,以某种方式显示所选选项的条目片段,它显示了片段a1

navBar.setOnNavigationItemReselectedListener {
    when(it.itemId) {
        R.id.optionA -> {

            // Removes all entries in the backstack if any
            if (supportFragmentManager.backStackEntryCount > 0) {
                supportFragmentManager.popBackStack(
                    null,FragmentManager.POP_BACK_STACK_INCLUSIVE
                )

                return@setOnNavigationItemSelectedListener true
            }

            // Replaces/add the entry fragment
            supportFragmentManager.beginTransaction()
                    .replace(R.id.fragmentHost, FragmentA1())
                    .commit()
            return@setOnNavigationItemSelectedListener true
        }

        R.id.optionB -> {
            // Removes all entries in the backstack up to BACK_STACK_HOME_TAG
            supportFragmentManager.popBackStack(
                BACK_STACK_HOME_TAG,
                FragmentManager.POP_BACK_STACK_INCLUSIVE
            )

            // Replace the fragment with the entry FragmentB1
            supportFragmentManager.beginTransaction()
                    .replace(R.id.fragmentHost, FragmentB1())
                    .addToBackStack(BACK_STACK_HOME_TAG)
                    .commit()

            return@setOnNavigationItemSelectedListener true
        }

        R.id.optionC -> {
            // Removes all entries in the backstack up to BACK_STACK_HOME_TAG
            supportFragmentManager.popBackStack(
                BACK_STACK_HOME_TAG,
                FragmentManager.POP_BACK_STACK_INCLUSIVE
            )

            // Replace the fragment with the entry FragmentC1
            supportFragmentManager.beginTransaction()
                    .replace(R.id.fragmentHost, FragmentC1())
                    .addToBackStack(BACK_STACK_HOME_TAG)
                    .commit()

            return@setOnNavigationItemSelectedListener true
        }

        ...

        return@setOnNavigationItemSelectedListener false
    }
}



override fun onBackPressed() {
    if (supportFragmentManager.backStackEntryCount > 0) {
        supportFragmentManager.popBackStack()
        return
    }

    super.onBackPressed()
}

【问题讨论】:

    标签: android kotlin bottomnavigationview fragment-backstack


    【解决方案1】:

    您应该只覆盖 BaseActivity 中的 Activity.OnBackPressed() 方法,您的每个活动都将继承该方法。 在该函数中,只需检查当前 Activity 是否为 A 类型。如果是,则退出应用程序,否则,启动 Activity A。

    【讨论】:

    • 实际上只是一项活动
    • 所以,只需检查当前显示的片段或 BottomNavigationView 中当前选定的项目,就可以在此活动上执行此操作。
    【解决方案2】:

    仅在添加片段 A1 时设置 BACK_STACK_HOME_TAG 状态。添加片段B1、C1、D1时无需弹回状态...
    覆盖片段 A1 中的 onKeyDown(),使其退出应用程序:
    System.exit(0);
    覆盖片段 B1、C1、D1...中的 onKeyDown(),将其设置回 A1,如:
    fragmentManager().popBackStack(BACK_STACK_HOME_TAG, 0);
    对于 A2、B2、C2、D2...,只需弹出自身即可返回 A1、B1、C1、D1...
    fragmentManager().popBackStack();

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-08-18
      • 2022-06-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-08
      • 1970-01-01
      相关资源
      最近更新 更多