友情提示:本文看的时候我是一路学习一路采坑 因此下面肯定会有很多坑的!!!
前面简单介绍了下NHF(NavHostFragment) . 通过NavHostFragment 我们并没有发现我们的Navigation下的开始目的地是如何被加载到我们NavHostFragment 或者说FragmentContainer中的. 本篇我们将追踪下是如何做到开始的目的地被加载进来的! 在前文Fragment/FragmentContainer中就有设置我们的NavGraph
app:navGraph="@navigation/nav_grah"
在NavHostFragment中提供了这么一个方法
@NonNull
public static NavHostFragment create(@NavigationRes int graphResId) {
return create(graphResId, null);
}
在Fml中(FragmentManagerlmpl)中我们可以发现相关内容
 在该方法中有大量的关于fragment属性操作 小细节 * id非常重要的哦 如果使用了name属性但是父组件没id/自身没id或者tag 是会出错的
Must specify unique android:id, android:tag, or have a parent with an id for " + fname)

也就是我们加载这样一段代码
<fragment
android:layout_width="match_parent"
android:id="@+id/basefragment"
android:name="com.kyli.mn.fragments.AFragment"
android:layout_height="match_parent"/>
而我们的fragment 其实已经是我们的NavHostFragment了 but我们依然没有找到从AttributeSet 中读取的graphid
but不好意思我浏览源码的时候忘记了… NavHostFragmnet中有onInflate方法有从AttributeSet中读取的代码…算了算了…上面代码就当梳理fragment的创建过程 把 上面说到 此时我们的Fragment已经指向了NavHostFragment
 这里便是我们读取到的位置. 那么现在我们找到了该id 下面回到开始 继续查看我们的第一目的地什么时候被加载进来的? 我目前沒有任何头绪 就根据日志开始追踪:! 
提示: MyNavHostFragment继承NavHost , Afragment 是我们导航开始地
我们发现在NHF被onAttach调用后就会调用 Afragment的初始化 but 我们的controller 是在onCreate方法中被初始化的
这很尴尬!
开始采坑了............
日志和我们想的不太一样… 所以我们继续回到 Fml的加载NHF的地方继续向下看 当调用完onInflate 后会将(addFragment)fragment添加到arraylist中并调用movetostate 其中

想说三个字… shitt !!! onattach后便调用了oncreate 方法!结合日志 我恍然醒悟,我日志肯定打错了位置,果然我把NHF中的log 放在了super.oncreate下面 因此其实NHF的oncreate已经被执行了 这下瞬间不懵逼了… 很明显了 我们的AFragment还是在控制器中处理了 —采坑结束
onacreate结束后便调用Afragmnent的初始化!!!"" 重新回到oncreate方法中初始化controller构造器 其中调用
mNavController.setGraph(mGraphId);
这句肯定非常关键,因为没有id 我们怎么找到Fragment对吧 …gointo
 inflate变回找到我们的NavGraph 也就是我们的xml 我们会在NavInflate 下发现大量的解析节点
这里忽略掉NavInflate的解析分析 作用就是封装我们xml的属性 到NAVGRAPH
随后便调用了onGraphCreated->navigate方法
而在navigate方法中是根据不同的Navigator 进行导航 因为这里我们调用的是fragment 因此 直接进入 FragmentNavigator

final Fragment frag = instantiateFragment(mContext, mFragmentManager,
className, args);
frag.setArguments(args);
进行创建了Fragment , 并开始事务
final FragmentTransaction ft = mFragmentManager.beginTransaction();//获取事务
ft.replace(mContainerId, frag);//替换了我们的container
ft.setPrimaryNavigationFragment(frag);//设置当前fragment为主要的Fragment 第一时间处理系统事件 如返回
总结
1.Fragment加载第一个目的地是在oncreate 中 setGraph时
2.navigate时 fragement导航 使用的是replace!!
|