请稍等 ...
×

采纳答案成功!

向帮助你的同学说点啥吧!感谢那些助人为乐的人

NavigationAPI调用问题

调用顺序:
HomeFragment-CategoryFragment-TagsFragment(循环调用)

调用代码
Home:
findNavController.navigate(R.id.category_fragment)
Category:
navController.navigate(
    R.id.tags_fragment,
    null,
    NavOptions.Builder()
        .setPopUpTo(
            destinationId = R.id.home_fragment,
            inclusive = true,
            saveState = true
        ).build()
)
Tags:
navController.navigate(R.id.home_fragment,null,NavOptions.Builder().setRestoreState(true).build())

日志:

启动:
HomeFragment-108038523-onCreate: null
HomeFragment-108038523-onResume: 
第一次点击:
HomeFragment-108038523-onPause: 
CategoryFragment-110566080-onCreate: null
HomeFragment-108038523-onDestroyView: 
CategoryFragment-110566080-onResume: 
第二次点击:
HomeFragment-108038523-onDestroy: 
CategoryFragment-110566080-onPause: 
CategoryFragment-110566080-onSaveInstanceState: 开始保存
TagsFragment-89193174-onCreate: null
CategoryFragment-110566080-onDestroyView: 
CategoryFragment-110566080-onDestroy: 
TagsFragment-89193174-onResume: 
以上一切正常
第三次点击:
TagsFragment-89193174-onPause: 
HomeFragment-9554669-onCreate: null
CategoryFragment-159926621-onCreate:xxxx(有值)
TagsFragment-89193174-onDestroyView: 
CategoryFragment-159926621-onResume: 
第四次点击:
HomeFragment-9554669-onSaveInstanceState: 开始保存
HomeFragment-9554669-onDestroy: 
CategoryFragment-159926621-onPause: 
CategoryFragment-159926621-onSaveInstanceState: 开始保存
TagsFragment-195906585-onCreate: null
CategoryFragment-159926621-onDestroyView: 
CategoryFragment-159926621-onDestroy: 
TagsFragment-195906585-onResume: 

疑问:
1.在Category当中调用inclusive包含目标出栈,saveState保存状态,
HomeFragment和CategoryFragment正常退出,
但是我的保存状态saveState是设置为true,
日志中可以看见只有CategoryFragment调用了onSaveInstanceState,为什么Home没有调onSaveInstanceState?saveState已经设置为true了,这样做不会保存目标栈的状态吗?

2.在第三次点击点击当中,在代码中可以看到我目标页面是HomeFragment,
可是为什么HomeFragment只做了创建并没有显示,而且还把HomeFragment下一级的CategoryFragment出来了,再到第四次点击的时候已经到了CategoryFragment代码当中导航导TagsFragment,HomeFragment和CategoryFragment出栈了这没有问题,可是这个时候HomeFragment又开始保存状态了呢?

正在回答

1回答

疑问1
saveState和inclusive同时设置为true,前者无效,因为目标页会被弹出栈,那么栈状态也没有保存的必要了。把inclusive=false时栈状态保存正常。

疑问2
setRestoreState(true)方法的作用是将导航状态保存并在回退时恢复。如果前面的页面调用了saveState=true的方法保存了状态,则在调用setRestoreState(true)方法时,会将前面所有页面的状态恢复了。
比如ABC三个页面,从A跳转到B,从B跳转到C时调用了setpopUpTo(destId=A, saveState=true,inclusuve=true)此时AB路由栈状态会被当做一个整体保存起来,详见NavController的navigate方法的1686行和583行。

那么再C页面执行restoreState=true.且目标页为A时,AB两个页面栈状态会一起恢复,此时B页面在上面对用户可见,A不可见。


第四次跳转到tagsfragment页面时,由于又执行了setpopUpTo(destId=A, saveState=true,inclusuve=true)此时AB路由栈状态会被当做一个整体保存。所以执行了onSaveInstanceState


不知道有没有讲明白呢?
1 回复 有任何疑惑可以回复我~
  • 提问者 chinaColby #1
    老师讲的很详细,谢谢老师
    回复 有任何疑惑可以回复我~ 2023-06-12 21:19:41
  • 提问者 chinaColby #2
    续疑问1:saveState和inclusive同时设置为true,目标页和当前页之间的页面都会弹出栈,既然都是弹出栈为什么只有目标页面没有保存?
    回复 有任何疑惑可以回复我~ 2023-06-13 08:59:57
  • LovelyChubby 回复 提问者 chinaColby #3
    对于ABC三个页面,A作为起始页,navigation在启动A页面时没有把它加入到fragmentManager内部的回退栈里,BC都在fragmentManager的回退栈里。详见fragmentNavigator的navigate方法187行
    虽然我们在B页面执行setPopUpTo(dest=A, inclusive=true,saveState=true)
    AB都会弹出栈,但是页面A不在回退栈,fragmentManager认为A页面不需要回退则不需要保存状态,所以不会触发onSaveInstanceState。  
    。
    回复 有任何疑惑可以回复我~ 2023-06-13 13:34:59

相似问题

登录后可查看更多问答,登录/注册

问题已解决,确定采纳
还有疑问,暂不采纳
意见反馈 帮助中心 APP下载
官方微信