一直使用Fragment进行发开,不过也遇到过很多问题,问题最大的就是回退栈管理。不过Google在今年5月IO大会发布了Navigation,用于更好的管理Fragment,并且可以图形化查看。目前版本1.0.0-alpha05,正式版可能会有不同。
Navigation的进阶使用
本来一开始想写简单使用,后来一想很多资料都有,直接来重点吧。
一、action
action分类:
一种是局部action,只能在FragmentOne为当前页面时,才可以使用,判断方法可以使用(navController无论是在activity中还是fragment都可以)
if (navController.currentDestination!!.id == R.id.fragmentOne) doSomeThing
另一种是全局action,只是在当前graph中使用,可以在任意页面使用。
action参数:
可以用来跳转fragment和activity
这里主要分析launchSingleTop、clearTask、popUpTo、popUpToInclusive
launchSingleTop
效果类似于Activity的SingleTop,栈顶复用模式。
clearTask
清空回退栈,已经弃用,谷歌推荐使用popUpTo(tag)、popUpToInclusive=true来实现,更加灵活。
popUpTo和popUpToInclusive
popUpTo(tag) 跳转到tag,并弹出tag之上的fragment,popUpToInclusive=true会弹出tag,false则不会弹出。
目前发现的问题
由于Navigation的设计原则问题,startDestination应该始终不会被弹出,所以弃用了clearTask,而popUpTo+popUpToInclusive=true 弹出startDestination,虽然可以,但是会导致toolbar回退键没有按照正常逻辑显示,点击会重启activity等问题。我在issuetracker上问过,然后谷歌工程师明确的表明了,这个不符合设计原则,所以不会修改。二、使用方法
1.配合toolbar和BottomNavigationView
在Activity中可以设置,
NavigationUI.setupActionBarWithNavController(this, navController)
NavigationUI.setupWithNavController(navigation, navController)
BottomNavigationView只需要将menu中item的id设置成fragment的id就可以,会自动调用item.getItemId(),来进行跳转。
2.统一配置Animation
fun getObjectNacAction(id: Int, singleTop: Boolean = true, popid: Int? = null, clearPop: Boolean = false) =
NavActionBuilder().apply {
destinationId = id
navOptions {
if (popid != null) {
popUpTo(popid) {
inclusive = clearPop
}
}
launchSingleTop = singleTop
anim {
popEnter = R.anim.slide_left_in
popExit = R.anim.slide_left_out
enter = R.anim.push_left_in
exit = R.anim.push_right_out
}
}
}
3.替换Graph
1.最简单的方法(目前没啥问题)
navController.popBackStack(R.id.startDestination, true)
navController.setGraph(R.navigation.new_navigation)
设置inclusive=true的时候,会弹出回退栈,并弹出回退栈中第一个位置的graph
设置inclusive=false的时候,不会弹出起始节点,也不会弹出回退栈中的graph
清空回退栈,然后设置新的graph,会自动判断新graph的startDestination,然后重新加载。如果不清空的话,会导致之前的页面不会消失,navController是属于之前的graph,但graph则是新的,无法找到新的action。
目前没有问题,可以正确适配toolbar。