Android Architecture Navigation-如何导航至Nav Graph建筑物后堆栈中的特定位置

Mic*_*bro 5 back-stack android-architecture-navigation

我有一个使用Android Arch Navigation创建的线性向导,我想像自然用户导航一样,在特定位置构建后退堆栈时启动它。所以我尝试了这种深层链接构建:

Bundle args = new Bundle();
args.putString("myarg", "From Widget");
 new NavDeepLinkBuilder(context)
    .setGraph(R.navigation.mobile_navigation)
    .setDestination(R.id.step_fragment)
    .setArguments(args)
    .createPendingIntent().send(); 
Run Code Online (Sandbox Code Playgroud)

这种方法的问题在于,由于用户将要进行构建导航,因此无法正确地构建回栈。步骤1->步骤2-> ...->步骤N仅保留步骤1->步骤N,即启动目标位置和导航图的目标位置。这不是我想要的。

第二个简单的办法是只调用多次navigate()navController。但是看起来很简单,却行不通

 protected fun navigateTo(step: Int) {
        val navController = findNavController(R.id.nav_host_fragment)

        if(step >= 0 && step < stepFragments.count()) {
            // go to step-th fragment
            if(navController.currentDestination.id != stepFragments.first()) return

            for(i in 0 until step) {
                navController.navigate(stepFragments[i])
            }
            navController.navigate(stepFragments[step])
        } else if(step == stepFragments.count()) {
            // go to confirm fragment
            navController.navigate(confirmFragment)
        } else {
            throw IndexOutOfBoundsException("Step index is out of wizard bounds!")
        }
    }
Run Code Online (Sandbox Code Playgroud)

它可以正确导航,但随后创建的返回堆栈是奇数,即“返回”按钮似乎起作用,但是来自的onNavigatedListener侦听器

navController.addOnNavigatedListener(this::onNavigatedListener)
Run Code Online (Sandbox Code Playgroud)

调用不正确。因此,我无法在向导中侦听片段更改。此外,由于连续按钮侦听器的navController.navigate(actionId)引发错误,NavController似乎已中断。

java.lang.IllegalArgumentException:此NavController的导航目标未知

更新!

用调试器拦截onBackPressed()似乎表明后退按钮按下不会调用navController.popBackStack(),并且navController.currentDestination属性不会更改。但是在NavHostFragment内部,片段正在改变。

Mic*_*bro 3

看来这个多步骤navController.navigate()工作正常。通过将默认的 onBackPressed() 行为重写为如下所示,可以将按“后退”按钮时的后退堆栈修复为预期行为:

 //region BACK PRESSED - CUSTOM BACK STACK HANDLING
    override fun onBackPressed() {
        if(!findNavController(R.id.nav_host_fragment).popBackStack()) {
            super.onBackPressed()
        }
    }
    //endregion
Run Code Online (Sandbox Code Playgroud)

并记录在案

protected fun navigateTo(step: Int) {
        val navController = findNavController(R.id.nav_host_fragment)

        if(step >= 0 && step < stepFragments.count()) {
            // go to step-th fragment
            if(navController.currentDestination.id != stepFragments.first()) return

            for(i in 0 until step) {
                navController.navigate(stepFragments[i])
            }
            navController.navigate(stepFragments[step])
        } else if(step == stepFragments.count()) {
            // go to confirm fragment
            navController.navigate(confirmFragment)
        } else {
            throw IndexOutOfBoundsException("Step index is out of wizard bounds!")
        }
    }
Run Code Online (Sandbox Code Playgroud)