处理片段后退导航和底部导航查看所选项目

时间:2019-06-11 18:59:33

标签: android kotlin bottomnavigationview fragment-backstack

我实现了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的动作,然后如果用户按下后退按钮,则应用应转到选项A,因为它在条目片段B1中,因此导航到选项B。 同样,如果用户使用底部导航视图a导航到选项A,然后按返回按钮,就像我们在出口处一样,我们应该完成该应用程序。

在OnNavigationItemSelectedListener中,我将当前片段替换为所选选项的条目片段,对选项AI以外的任何选项使用beginTransaction.replace来添加addToBackStack(null),但是仅此一项与所需的导航不匹配,因为如果用户按下后退按钮,就可以导航到选项A,它可以导航到先前选择的选项。 A还尝试在使用popBackStack(BACK_STACK_HOME_TAG, FragmentManager.POP_BACK_STACK_INCLUSIVE)替换片段并替换添加addToBackStack(BACK_STACK_HOME_TAG)之前弹出后座,但是以某种方式选择第二个选项而不是显示所选选项的条目片段时,它会显示片段A1 < / p>

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()
}

2 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分:0)

仅在添加片段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();