Jetpack学习(一)——navigation

官方才是最好的学习途径

navigation官方文档

导航组件由以下三个关键部分组成:

  • 导航图:在一个集中位置包含所有导航相关信息的 XML 资源。这包括应用内所有单个内容区域(称为目标)以及用户可以通过应用获取的可能路径。
  • NavHost:显示导航图中目标的空白容器。导航组件包含一个默认 NavHost 实现 (NavHostFragment),可显示 Fragment 目标。
  • NavController:在 NavHost 中管理应用导航的对象。当用户在整个应用中移动时,NavController 会安排 NavHost 中目标内容的交换。

注意:如果要在Android Studio中使用导航,则必须使用Android Studio 3.3或更高版本。

1.app的 build.gradle做如下引用

  implementation "androidx.navigation:navigation-fragment:2.1.0"
  implementation "androidx.navigation:navigation-ui:2.1.0"

2.resNewDirectory,新建名字为navigation的文件夹(右键操作)

3.navigationNewNavigation resource file新建main_navigation.xml(右键操作),切换为Text视图后,代码如下

main_navigation.xml

<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/main_navigation"
    >

</navigation>

4.创建并且链接destination

切换到Design(设计视图),找到左上角新增图标,按自己的需求新建destination


创建

新建完成后并为对应的destination设置连接
单击Navigation视图出现圆点,拖动圆点指向对应跳转的视图


创建完成,并且链接

main_navigation.xml

<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/main_navigation"
    app:startDestination="@id/homeFragment">

    <fragment
        android:id="@+id/homeFragment"
        android:name="com.hwp.jetpacktest2.HomeFragment"
        android:label="fragment_home"
        tools:layout="@layout/fragment_home" >
        <action
            android:id="@+id/action_homeFragment_to_registerFragment"
            app:destination="@id/registerFragment" />
        <action
            android:id="@+id/action_homeFragment_to_loginFragment"
            app:destination="@id/loginFragment" />
    </fragment>
    <fragment
        android:id="@+id/loginFragment"
        android:name="com.hwp.jetpacktest2.LoginFragment"
        android:label="fragment_login"
        tools:layout="@layout/fragment_login" />
    <fragment
        android:id="@+id/registerFragment"
        android:name="com.hwp.jetpacktest2.RegisterFragment"
        android:label="fragment_register"
        tools:layout="@layout/fragment_register" />
</navigation>

5.修改activity_main.xml

    <fragment
        app:layout_constraintTop_toTopOf="parent"
        android:id="@+id/my_nav_host_fragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        app:navGraph="@navigation/main_navigation"
        app:defaultNavHost="true"
        android:layout_width="match_parent"
        app:layout_constraintBottom_toBottomOf="parent"
        android:layout_height="match_parent"/>
android:name="androidx.navigation.fragment.NavHostFragment" //这个必须这样写
app:navGraph="@navigation/main_navigation"  //navigation文件夹中的对应的navigation资源文件
app:defaultNavHost="true" //与系统返回键相关联的

6.处理点击事件

    public void onClick(View view) {
        switch (view.getId()){
            case R.id.btn_login:
                Navigation.findNavController(view).navigate(R.id.action_homeFragment_to_loginFragment);
                break;
            case R.id.btn_register:
                Navigation.findNavController(view).navigate(R.id.action_homeFragment_to_registerFragment);
                break;
        }
    }

注意:对应的main_navigation.xml中destination千万不要链接错误。否则点击事件写了,程序代码本身不会报错,编译后一定会崩掉的!!!!

7.跳转后回退事件,一般指的是页面上的Toolbar回退按钮

 Navigation.findNavController(view).popBackStack();

8.数据传递与接收

main_navigation.xml切换到Design,点击需要,接收数据的destination按如下图操作

操作界面1

操作界面2

Name---为传递数据对应的key
Type---为数据格式
Default Value---为默认值
备注:数据可以为一个或者多个,此处key和数据类型,要与下文对应上。

修改点击事件,传递事件

private Bundle bundle;
    public void onClick(View view) {
        switch (view.getId()){
            case R.id.btn_login:
                bundle=new Bundle();
                bundle.putInt("arg",-1);
                Navigation.findNavController(view).navigate(R.id.action_homeFragment_to_loginFragment,bundle);
                break;
            case R.id.btn_register:
                bundle=new Bundle();
                bundle.putString("arg","我是数据~");
                Navigation.findNavController(view).navigate(R.id.action_homeFragment_to_registerFragment,bundle);
                break;
        }
    }

接收数据的destination按如下图操作
LoginFragment.java

getArguments().getInt("arg");

RegisterFragment.java

getArguments().getString("arg");

9.最后未解决问题,如实现类似如startActivityForResultonActivityResult数据回调~以及Deep Links的使用~还有动画的研究!!