美文网首页jetpack
Navigation使用笔记--基本用法

Navigation使用笔记--基本用法

作者: 紫鹰 | 来源:发表于2022-07-03 18:12 被阅读0次

Navigation是什么

jetpack组件,可视化管理Fragment切换

接入过程

gradle 配置

模块gradle配置

implementation "androidx.navigation:navigation-fragment-ktx:2.4.1"
implementation "androidx.navigation:navigation-ui-ktx:2.4.1"

plugins {
    ...
    id "androidx.navigation.safeargs.kotlin"
}

项目gradle配置

buildscript {
        ...
        dependencies {
        classpath "androidx.navigation:navigation-safe-args-gradle-plugin:2.3.5"
    }
}
activity的布局文件中
<androidx.constraintlayout.widget.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <androidx.fragment.app.FragmentContainerView
        android:id="@+id/nav_host"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:defaultNavHost="true"
        app:navGraph="@navigation/nav_setting" />

</androidx.constraintlayout.widget.ConstraintLayout>
  • 布局容器为androidx.fragment.app.FragmentContainerView

  • android:name="androidx.navigation.fragment.NavHostFragment" 为固定写法

  • app:navGraph="@navigation/nav_setting" 为指定跳转控制器

接下来看一下navigation如何配置的

res下新建navigation文件夹,在该文件夹下新建 选择 Navigation resource file

以下为一个标准示例

<?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/nav_test"
    app:startDestination="@id/fragment1">

    <fragment
        android:id="@+id/fragment1"
        android:name="com.relax.myapplication.navigationtest.Fragment1"
        tools:layout="@layout/fragment_1"
        android:label="fragment1">
        <action
            android:id="@+id/action_fragment1_to_fragment2"
            app:destination="@id/fragment2"
            app:enterAnim="@anim/base_slide_right_in"/>
    </fragment>

    <fragment
        android:id="@+id/fragment2"
        android:name="com.relax.myapplication.navigationtest.Fragment2"
        tools:layout="@layout/fragment_2"
        android:label="fragment2">
        <action
            android:id="@+id/action_fragment2_to_fragment3"
            app:destination="@id/fragment3" 
            app:enterAnim="@anim/base_slide_right_in"/>
    </fragment>

    <fragment
        android:id="@+id/fragment3"
        android:name="com.relax.myapplication.navigationtest.Fragment3"
        tools:layout="@layout/fragment_3"
        android:label="fragment3"/>

</navigation>

根标签为navigation:

  • 属性id用于被activity_layout中引用

  • 属性startDestination为该activity中起始展示的页面

子标签 fragment 为fragment相关配置

  • 属性id,当前navigation文件中fragment的id

  • 属性name,fragment的路径地址

  • 属性layout,fragment的布局文件

fragment的子标签action,为跳转相关配置

  • 属性id,当前action的id,一般在代码中使用

  • 属性destination,跳转目标fragment的id

  • 属性enterAnim,fragment进入动画

  • 属性exitAnim,fragment移除动画

在程序中使用
  • activity中使用

    val navController = findNavController(R.id.nav_host_fragment)
    navController.navigate(R.id.action_fragment2_to_fragment3)
    
  • fragment中使用

    getView()?.findViewById<TextView>(R.id.tv_to_f2)?.setOnClickListener {
        findNavController().navigate(R.id.action_fragment1_to_fragment2)
    }
    

可以看出相比FragmentManger 代码简洁易维护

跳转传参

跳转控制建议使用SafeArgs Gradle插件

优势 传参友好。使用get、set方式传惨,避免了key造成的耦合

fragment标签下的子标签配置

<?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/nav_test"
    app:startDestination="@id/fragment1">

    <fragment
        android:id="@+id/fragment1"
        android:name="com.relax.myapplication.navigationtest.Fragment1"
        tools:layout="@layout/fragment_1"
        android:label="fragment1">
        <action
            android:id="@+id/action_fragment1_to_fragment2"
            app:destination="@id/fragment2" />
        <argument
            android:name="plantName"
            app:argType="string" />
        <argument
            android:name="plantId"
            app:argType="string" />
    </fragment>

    <fragment
        android:id="@+id/fragment2"
        android:name="com.relax.myapplication.navigationtest.Fragment2"
        tools:layout="@layout/fragment_2"
        android:label="fragment2">

        <action
            android:id="@+id/action_fragment2_to_fragment3"
            app:destination="@id/fragment3" />
    </fragment>

</navigation>

设置参数

 var bundle = Fragment1Args("name","id").toBundle()
 findNavController().navigate(R.id.action_fragment1_to_fragment2,bundle)

获取参数

    arguments?.let { 
        var id = Fragment2Args.fromBundle(it).plantId 
    }
    Fragment2Args.fromBundle(requireArguments()).plantName
劣势
  • 回退事件,在activity中可以通过startActivityForResult的方式回传参数,这里就比较复杂

  • 底层实际调用replace方法,故无法保存状态

不出意外的话,下篇文章会介绍如何弥补以上两个劣势

参考资料

https://www.jianshu.com/p/5cd63ecabbf5

https://blog.csdn.net/weixin_42046829/article/details/110466717

https://www.cnblogs.com/guanxinjing/p/11555217.html

https://zhuanlan.zhihu.com/p/96787354

https://github.com/winlee28/Jetpack-WanAndroid

相关文章

网友评论

    本文标题:Navigation使用笔记--基本用法

    本文链接:https://www.haomeiwen.com/subject/wpadbrtx.html