5

我有一个使用 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(); 

这种方法的问题是它不能正确构建回栈,因为用户将构建导航步骤 1 -> 步骤 2 -> ... -> 步骤 N 它只包含步骤 1 -> 步骤 N,即开始目的地和导航图的目标目的地。这不是我想要的。

第二种简单的方法是多次调用navigate()on 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!")
        }
    }

它导航正确,但创建的返回堆栈很奇怪,即返回按钮似乎工作,但onNavigatedListener监听器来自

navController.addOnNavigatedListener(this::onNavigatedListener)

没有正确调用。所以我不能听向导中的片段变化。此外,NavController 似乎已中断,因为连续按钮侦听器的 navController.navigate(actionId) 会引发错误。

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

更新!

用调试器拦截 onBackPressed() 似乎表明 Back Button Press 没有调用 navController.popBackStack() 并且 navController.currentDestination 属性没有改变。但是在 NavHostFragment 内部,片段正在发生变化。

4

1 回答 1

3

似乎这个多步骤navController.navigate()工作正常。并且可以通过将默认 onBackPressed() 行为覆盖为以下内容来实现在按下 Back 按钮时将返回堆栈修复为预期行为:

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

并记录在案

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!")
        }
    }
于 2018-08-03T13:24:05.810 回答