欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Android Jetpack Navigation组件使用,跳转,传参,action,回退,动态加载等

程序员文章站 2022-06-25 09:03:48
简介Navigation是Jetpack组件库的一部分,于2018年推出;主要用于Fragment的管理,及之间的跳转等,使单Activity架构更简单;使用条件AndroidStudio版本需3.2及以上版本module下的build.gradle添加依赖,根据自己项目的语言选择性添加依赖;dependencies { def nav_version = "2.3.0" // Java language implementation implementation "an...

目录

一,简介

二,使用条件

三,主要组成

四,主要功能

五,使用

1,创建Navigation Graph导航图

3,编辑导航图,将目的地添加到导航图

4,连接目的地

5,将NavHostFragment添加到Activity中

6,跳转

7,全局的action

8,数据传递

9,回退

10,动态加载


一,简介

Navigation是Jetpack组件库的一部分,于2018年推出;主要用于Fragment的管理,及之间的跳转等,使单Activity架构更简单;

二,使用条件

1,AndroidStudio版本需3.2及以上版本

2,module下的build.gradle添加依赖,根据自己项目的语言选择性添加依赖;

dependencies {
  def nav_version = "2.3.0"

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

  // Kotlin
  implementation "androidx.navigation:navigation-fragment-ktx:$nav_version"
  implementation "androidx.navigation:navigation-ui-ktx:$nav_version"
}

关于依赖配置问题可以查看官网资料:https://developer.android.com/jetpack/androidx/releases/navigation

官网文档地址:https://developer.android.com/guide/navigation

本文使用的AndroidStudio版本号是4.0.1;

三,主要组成

  • Navigation Graph :导航图是一个xml资源;创建于res/navigation/下;
  • NavHostFragment:类似于一个容器,使Navigation Graph添加其中;
  • NavController:处理Fragment间的跳转(Kotlin / Java对象);

四,主要功能

  1. 视觉导航图
  2. 按目的地和动作导航
  3. 过渡动画
  4. 菜单导航,底部导航和菜单抽屉导航
  5. 类型安全参数传递
  6. 深层连结

目的地可以理解为Fragment或者Activity还可以是另一个导航图;有的时候也叫目标;

五,使用

1,创建Navigation Graph导航图

右键项目new —>Android Resource File,填写File name名字自定义这里就叫navi_graph,Resource type选择Navigation,Directory name使用navigation;

Android Jetpack Navigation组件使用,跳转,传参,action,回退,动态加载等

注意:将导航图添加到项目中时,如果尚未将导航依赖项添加到应用程序的build.gradle文件中,则Android Studio会显示提示并为您添加依赖项。

<?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"
    android:id="@+id/navi_graph">

</navigation>
  • <navigation> 是每个导航图的根节点。
  • <navigation>包含一个或多个以<activity>或表示的目的地<fragment>。
  • app:startDestination 是一个属性,它指定用户首次打开应用程序时默认启动的目的地。 

在导航编辑器中,可以直观地编辑导航图也可也直接编辑XML。

Android Jetpack Navigation组件使用,跳转,传参,action,回退,动态加载等

主要分不分:

  1.  “目标”面板:列出导航主机和“ 图形编辑器”中当前存在的所有目标。
  2. 图形编辑器:包含导航图的可视表示。可以在“ 设计”视图和“ 文本”视图中的基础XML表示形式之间切换。
  3. 属性:在导航图中显示当前选定项目的属性。

3,编辑导航图,将目的地添加到导航图

进入导航图navi_graph.xml编辑模式下,点击右上角的Split,一个导航图是包含所有的目的地和Action的XML资源文件;

Android Jetpack Navigation组件使用,跳转,传参,action,回退,动态加载等

第一种方式

点击进入New Destination,选择Create new Destination 以这个为例;创建一个Fragment,名字叫FirstFragment

Android Jetpack Navigation组件使用,跳转,传参,action,回退,动态加载等

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/navi_graph"
    app:startDestination="@id/firstFragment">

    <fragment
        android:id="@+id/firstFragment"
        android:name="com.example.navigationdemo.FirstFragment"
        android:label="fragment_first"
        tools:layout="@layout/fragment_first" />
    <fragment
        android:id="@+id/secondFragment"
        android:name="com.example.navigationdemo.SecondFragment"
        android:label="fragment_second"
        tools:layout="@layout/fragment_second" />
    <fragment
        android:id="@+id/thirdFragment"
        android:name="com.example.navigationdemo.ThirdFragment"
        android:label="fragment_third"
        tools:layout="@layout/fragment_third" />

</navigation>

多创建几个Fragment,后面讲跳转会用到;

注意:app:startDestination="@id/firstFragment"类似于MainActivity;fragment标签的属性可以通过单击一个目标以将其选中,然后在“ 属性”面板中修改和设置,也可直接编辑XML;

第二种方式

如果之前新建好了Fragment,这里可以点击进入New Destination找到之前新建好的Fragment引入即可,比如我之前已经有了一个TestFragment其布局为fragment_test;这里显示的是其布局文件名;

Android Jetpack Navigation组件使用,跳转,传参,action,回退,动态加载等

4,连接目的地

上面有提到一个导航图还包含Action标签,这个就是目的地间逻辑连接,它可以在navigation标签下,也可以在fragment标签下;action标签还有destination 属性是表示目的地,要跳转到哪里的;还有个id属性,它和其他控件id含义一样,对比理解就好;在XML中通过action标签、属性destination,id就可实现目标的连接;

或者通过导航编辑器连接两个目的地:

在“ Design”选项卡中,将鼠标悬停在您要用户导航的目标的右侧。在目标的右侧上方将出现一个圆圈

Android Jetpack Navigation组件使用,跳转,传参,action,回退,动态加载等

点击圆圈并拖动鼠标,拖到想要连接的另一个目的地,两个目的地之间的结果线代表一个动作;

Android Jetpack Navigation组件使用,跳转,传参,action,回退,动态加载等

单击文本选项卡切换到XML视图。现在将action添加到id为firstFragment源目标。该action具有一个id和一个destination属性,destination属性值包含的是下一个目的地的id,如以下示例所示:

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

    <fragment
        android:id="@+id/firstFragment"
        android:name="com.ang.navigationtest.FirstFragment"
        android:label="fragment_first"
        tools:layout="@layout/fragment_first" >
        <action
            android:id="@+id/action_firstFragment_to_secendFragment"
            app:destination="@id/secendFragment" />
    </fragment>
    <fragment
        android:id="@+id/secendFragment"
        android:name="com.ang.navigationtest.SecendFragment"
        android:label="fragment_secend"
        tools:layout="@layout/fragment_secend" />
    <fragment
        android:id="@+id/thirdFragment"
        android:name="com.ang.navigationtest.ThirdFragment"
        android:label="fragment_third"
        tools:layout="@layout/fragment_third" />
</navigation>

 请注意,要实际导航到目的地,仍然需要编写代码来执行导航。这个后面将跳转在具体说;

5,将NavHostFragment添加到Activity中

也是有两种方式:

第一种方式

在MainActivity的activity_main.xml布局中编写;具体代码如下,name是固定的不能修改,navGraph属性值是

<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

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

  </androidx.constraintlayout.widget.ConstraintLayout>

app:defaultNavHost="true":让 Navigation 容器处理返回事件,在 Navigation 容器中如果有页面的跳转,点击返回按钮会先处理 容器中 Fragment 页面间的返回,处理完容器中的页面,再处理 Activity 页面的返回。如果值为 false 则直接处理 Activity 页面的返回。这里你能会发现,刚才navigation graph中爆红,现在消失了;

第二种方式:

如果你的Activity布局使用的约束布局的话,在布局的视图Split下,Containers中拖拽一个NavHostFragment,然后选择自己的导航图文件即可;别忘了设置约束哦

Android Jetpack Navigation组件使用,跳转,传参,action,回退,动态加载等

Android Jetpack Navigation组件使用,跳转,传参,action,回退,动态加载等

6,跳转

要实现目的地间的跳转,是通过NavController

获取NavController主要有三种方式

NavHostFragment.findNavController(Fragment)
Navigation.findNavController(Activity, @IdRes int viewId)
Navigation.findNavController(View

好像这种也是可以的

FragmentManager supportFragmentManager = getActivity().getSupportFragmentManager();
NavHostFragment navHostFragment = (NavHostFragment) supportFragmentManager.findFragmentById(R.id.fragment);
NavController navController = navHostFragment.getNavController();

然后通过NavController 的navigate方法实现跳转;这里的resId可以是导航图中的目的地fragment的id,也可以是源目的地的action的id;

//navigate方法
public void navigate(@IdRes int resId) {
     navigate(resId, null);
}

也可以通过如下方式实现跳转

view.findViewById(R.id.btn_to_secend).setOnClickListener( Navigation.createNavigateOnClickListener(R.id.secendFragment, null));

7,全局的action

上面有提到在navigation标签下也可以添加action,这个就是全局的action,可以解决多个源目的地跳转到同一个目的地,不用每个源目的地中都写同一个action了,准确的说应该是destination属性;

8,数据传递

NavController 的navigate跳转方法还有个重载方法,有个Bundle参数,所以可通Bundle实现目的地间的数据传递;

public void navigate(@IdRes int resId, @Nullable Bundle args) {
     navigate(resId, args, null);
}

9,回退

既然NavController可以实现跳转,那么相似的功能回退呢,当然也可以实现,NavController有 navigateUp() 和 popBackStack() 两个方法可以返回上一级;

10,动态加载

可以在Fragment或者Activity中动态加载Navigation:

FragmentManager supportFragmentManager = getSupportFragmentManager();
NavHostFragment navHostFragment = (NavHostFragment) supportFragmentManager.findFragmentById(R.id.fragment);
NavController navController = navHostFragment.getNavController();
navController.setGraph(R.navigation.nav_graph);
NavHostFragment也是一个Fragment;可以当作一个Fragment使用;

本文地址:https://blog.csdn.net/ezconn/article/details/108671409

相关标签: Android