Jetpack之Navigation源码解析

为了避免歧义,本文所引用的Navigation版本为:2.3.2,Navigation的官网文档地址为:Navigation 组件使用入门

	def nav_version = "2.3.2"
    // Java language implementation
    implementation "androidx.navigation:navigation-fragment:$nav_version"
    implementation "androidx.navigation:navigation-ui:$nav_version"

本文试图为读者搭建出Navigation库的内部导航过程,以一个Activity和多个Fragment组成的功能页面来作为分析的对象,这里多说一句,看源码有一个技巧,就是所谓“抓大放小”,抓住主要流程,忽略次要部分,这样才不会被淹没在源码的海洋里。

NavHostFragment(导航宿主Fragment)

一般在使用NavHostFragment时是在Activity的布局文件中进行配置,如下:

<androidx.fragment.app.FragmentContainerView
        android:id="@+id/my_nav_host_fragment"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="9"
        android:name="androidx.navigation.fragment.NavHostFragment"
        app:defaultNavHost="true"
        app:navGraph="@navigation/nav_graph_main"/>

我们进入NavHostFragment内部查看其源码,首先,它继承自Fragment,实现了NavHost接口

public class NavHostFragment extends Fragment implements NavHost {
   }

代码执行到NavHostFragment内部之后,第一个被执行的方法是

  1. onInflate()
public void onInflate(@NonNull Context context, @NonNull AttributeSet attrs,
            @Nullable Bundle savedInstanceState) {
   
        super.onInflate(context, attrs, savedInstanceState);

        final TypedArray navHost = context.obtainStyledAttributes(attrs,
                androidx.navigation.R.styleable.NavHost);
        final int graphId = navHost.getResourceId(
                androidx.navigation.R.styleable.NavHost_navGraph, 0);
        if (graphId != 0) {
   
            mGraphId = graphId;//解析出导航图ID
        }
        navHost.recycle();

        final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.NavHostFragment);
        final boolean defaultHost = a.getBoolean(R.styleable.NavHostFragment_defaultNavHost, false);
        if (defaultHost) {
   
            mDefaultNavHost = true;//解析出标示是否是默认导航宿主
        }
        a.recycle();
    }

本方法有2个目的。

目的1、解析出导航图ID:mGraphId,其对应的配置属性为:

app:navGraph="@navigation/nav_graph_main"

mGraphId解析出来的值为:@navigation/nav_graph_main,是导航图的真实路径。

目的2、解析出标示是否是默认导航宿主的属性mDefaultNavHost,对应的配置信息是:

app:defaultNavHost="true"

接下来,代码会执行到NavHostFragment生命周期的

  1. onCreate()
public void onCreate(@Nullable Bundle savedInstanceState) {
   
        final Context context = requireContext();

        mNavController = new NavHostController(context);//1
        mNavController.setLifecycleOwner(this);
        mNavController.setOnBackPressedDispatcher(requireActivity().getOnBackPressedDispatcher());
        // Set the default state - this will be updated whenever
        // onPrimaryNavigationFragmentChanged() is called
        mNavController.enableOnBackPressed(
                mIsPrimaryBeforeOnCreate != null && mIsPrimaryBeforeOnCreate);
        mIsPrimaryBeforeOnCreate = null;
        mNavController.setViewModelStore(getViewModelStore());
        onCreateNavController(mNavController);//2

        Bundle navState = null;
        ......
        if (mGraphId != 0) {
   
            // Set from onInflate()
            mNavController.setGraph(mGraphId);//3
        } else {
   
            // See if it was set by NavHostFragment.create()
            final Bundle args = getArguments();
            final int graphId = args != null ? args.getInt(KEY_GRAPH_ID) : 0;
            final Bundle startDestinationArgs = args != null
                    ? args.getBundle(KEY_START_DESTINATION_ARGS)
                    : null;
            if (graphId != 0) {
   
                mNavController.setGraph(graphId, startDestinationArgs);
            }
        }
        ......
    }

本方法创建了NavHostController的对象mNavController,并设置了一系列属性,在注释代码1处,我们进入

  1. NavHostController
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值