最近的项目中使用了Navigation组件,使用此组件来实现界面跳转栈,分享一个使用时遇到的一个问题
Navigation的流程图:
微信截图_20200426160606.png
从userFragment一直进入到changePasswordNextFragment,当我在栈顶的逻辑做完后,需要回到userFragment时,Navigation组件是有提供了两个弹出栈的方法
findNavController().popBackStack()
findNavController().popBackStack(@IdRes int destinationId, boolean inclusive)
由于此时的需求是要回到userFragment,因此此时需要用的就是带有参数的popBackStack(@IdRes int destinationId, boolean inclusive)
两个参数中,第一个@IdRes int destinationId
不难理解,就是要到达的目标fragment的id,也就是在navigation.xml文件中Fragment的id,
第二个参数boolean inclusive
是个布尔值,点进去看popBackStack
的源码
* Attempts to pop the controller's back stack back to a specific destination.
*
* @param destinationId The topmost destination to retain
* @param inclusive Whether the given destination should also be popped.
*
* @return true if the stack was popped at least once and the user has been navigated to
* another destination, false otherwise
*/
public boolean popBackStack(@IdRes int destinationId, boolean inclusive) {
boolean popped = popBackStackInternal(destinationId, inclusive);
// Only return true if the pop succeeded and we've dispatched
// the change to a new destination
return popped && dispatchOnDestinationChanged();
}
看源码最头疼的就是翻译了,当时直接对整段注释进行翻译
硬核翻译,当时看到中文注释第二个参数的上的翻译
是否也应弹出给定的目的地
,当时没有完全理解,认为应该设置为true,然后实验也的确能够回到userFragment,直到今天,测试逻辑顺序后,准备进入其他的界面时,然后就报错了奉上错误日志
java.lang.IllegalArgumentException
navigation destination com.jzit168.conferencelive:id/action_userFragment_to_updateVersionFragment is unknown to this NavController
解析原始
1 androidx.navigation.NavController.navigate(NavController.java:863)
2 androidx.navigation.NavController.navigate(NavController.java:804)
3 androidx.navigation.NavController.navigate(NavController.java:790)
4 androidx.navigation.NavController.navigate(NavController.java:778)
5 com.jzit168.conferencelive.ui.user.view.UserFragment$initListener$4.onClick(UserFragment.kt:36)
6 android.view.View.performClick(View.java:7261)
7 android.view.View.performClickInternal(View.java:7238)
8 android.view.View.access$3500(View.java:815)
9 android.view.View$PerformClick.run(View.java:27531)
10 android.os.Handler.handleCallback(Handler.java:883)
11 android.os.Handler.dispatchMessage(Handler.java:100)
12 android.os.Looper.loop(Looper.java:227)
13 android.app.ActivityThread.main(ActivityThread.java:7550)
14 java.lang.reflect.Method.invoke(Native Method)
15 com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:539)
16 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:953)
关键错误is unknown to this NavController
需要进入的Fragment变成未知的,找到错误日志,赶紧百度一波,结果发现搜到的错误日志差不多相似,但是产生的原因不一致,别人的说是连续点击造成的,但我的却并不是这个原因造成的啊,找来找去,找来找去,直到我看到了这样一篇文章中对页面跳转和指定页面跳转参数的解释
app:popUpToInclusive
的理解应该是当前属于弹出栈
也会是说目标Fragment是否属于弹出栈?
突然恍然大悟,然后再去看源码中单独对第二个参数进行翻译
给定的目的地是否也应该弹出
,这不就是在问目标Fragment是否也要弹出,那么这个就不难理解了,我跳到特定的Fragment,但是我不需要把目标fragment也弹出的,所以该设为false
啊,然后代码中将true改为false后,再次测试,果然没有报相关的错误了,也能正常进出问题到这也就解决了,
这也引发了我的思考:如何才能更有效的理解相关的源码呢?
我目前也就想到一点,那就是源码相关注释一定要理解到位,注释该单句翻译理解就要单句理解,混合翻译可能会产生不一样的解释
最后附上提醒了我错误地方的文章链接
最全面的Navigation的使用指南
网友评论