android Jetpack组件Navigation导航组件--组件间跳转、组件间传值功能实现

简介: android Jetpack组件Navigation导航组件--组件间跳转、组件间传值功能实现

1 github 代码地址


边看代码边读文章效果更佳呦

github.com/ymeddmn/Jet…


2 Navigation 简单使用


Navigation 是 google Jetpack 组件库的应用导航解决方案,用于 Activity、Fragment 之间进行页面跳转。Navigation 会提供一个 xml 负责管理各个导航组件直接的关系


2.1 使用入门

2.1.1 简单实现两个 fragment 的跳转

代码所在分支:simple-use

1、添加依赖
dependencies {
  def nav_version = "2.3.5"
  // 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"
  // Feature module Support
  implementation "androidx.navigation:navigation-dynamic-features-fragment:$nav_version"
  // Testing Navigation
  androidTestImplementation "androidx.navigation:navigation-testing:$nav_version"
  // Jetpack Compose Integration
  implementation "androidx.navigation:navigation-compose:1.0.0-alpha10"
}
复制代码


2、创建导航关系图

在 xml 文件夹下面创建一个 navigation1.xml 文件,用来存放两个 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/jjj" <!---->
    app:startDestination="@id/originFragment">
    <fragment
        android:id="@+id/originFragment"
        android:name="com.mage.navigationdemo.OriginFragment"
        android:label="fragment_origin"
        tools:layout="@layout/fragment_origin" >
        <action
            android:id="@+id/action_originFragment_to_destiationFragment"
            app:destination="@id/destiationFragment" />
    </fragment>
    <fragment
        android:id="@+id/destiationFragment"
        android:name="com.mage.navigationdemo.DestiationFragment"
        android:label="fragment_destiation"
        tools:layout="@layout/fragment_destiation" />
</navigation>
复制代码


下面表格是各个重要标签属性的说明

属性标签名 作用
navigation 导航组件的根标签
startDestination 第一次进入页面展示的组件标签
fragment-id 视图中 fragment 的 id,导航用
fragment-name Fragment 或 Activity 的全类名
action-destination 目的地的视图 id

3、Activity 布局文件配置

在 activity 的布局文件中加入导航组件容器

<androidx.fragment.app.FragmentContainerView
        android:id="@+id/nav_host_fragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:defaultNavHost="true"
        app:navGraph="@navigation/nav_graph" />
复制代码


属性标签名 作用
FragmentContainerView-name 固定写法
FragmentContainerView-navGraph 所关联的 xml 视图
FragmentContainerView-navGraph 确保可以拦截系统的返回键,如果设置 false 就无法进行回退操作

4、创建两个 Fragment

创建 OriginFragment.kt DestiationFragment.kt 两个 Fragment,这两个 fragment 就是常规的 fragment 创建 在第二条的 navigation 中我们将 OriginFragment 设置为了主 Fragment,既 activity 打开后首次展示的 Fragment


5、实现 OriginFragment 跳转到 DestiationFrament

OriginFragment 中添加按钮点击事件,navigate 可以实现跳转的 DestiationFragment 的效果

btn.setOnClickListener {
            val findNavController = findNavController()
            findNavController.navigate(R.id.destiationFragment)
        }
复制代码

R.id.destiationFragment 即是第 2 步中我们在 navigation 中给 DestiationFrgment 设置的 id


6、最终实现效果展示

image.png


2.1.2 实现 activity 跳转到 activity 操作

代码实现在分支:activity2activity


2.1.1 中实现的是 Fragment 和 Fragment 直接的路由,本例中我们要实现从一个 Activity 跳转到另一个 Activity 的操作

1、基本配置

本例中实现 MainActivity 跳转到 DesActivity 的操作,MainActivity 中依然要添加一个 FragmentContainerView 控件以及一个 OriginFragment。


2、导航图代码

本例导航图中需要配置 MainActivity 和 DesActivity,DesActivity 就是我们要跳转到的 Activity

<?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/navigation1"
    app:startDestination="@id/originFragment">
    <activity
        android:id="@+id/mainActivity"
        android:name="com.mage.navigationdemo.MainActivity"
        android:label="activity_main"
        tools:layout="@layout/activity_main" />
    <activity
        android:id="@+id/desActivity"
        android:name="com.mage.navigationdemo.DesActivity"
        android:label="activity_des"
        tools:layout="@layout/activity_des" />
    <fragment
        android:id="@+id/originFragment"
        android:name="com.mage.navigationdemo.OriginFragment"
        android:label="fragment_origin"
        tools:layout="@layout/fragment_origin" />
</navigation>
复制代码


3、MainActivity 中点击跳转的代码

MainActivity 中添加按钮点击进行跳转操作: R.id.nav_host_fragment 就是 MainActivity 布局文件中 FragmentContainerView 的 id,我们通过 id 拿到 NavController,通过 Controller 实现跳转到 DesActivity 的操作

findViewById<Button>(R.id.btn_des).setOnClickListener {
            findNavController(R.id.nav_host_fragment).navigate(R.id.desActivity)
        }
复制代码


4、实现效果

image.png


3 导航间数据传递


导航间数据传递有两种方式 Bundle 和 Safe Args 两种方式,其中 Safe Args 需要基于 gradle 插件,下面分别介绍一下两种方式:


3.1 Bundle 方式传递数据

这个很简单直接上代码

btn.setOnClickListener {
            val findNavController = findNavController()
            findNavController.navigate(R.id.destiationFragment, bundleOf("param1" to "我是AFragment传过来的参数"))
        }
复制代码


3.2 Safe Args 方式传递数据

这种方式需要基础插件

该插件可以生成简单的 object 和 builder 类,以便以类型安全的方式浏览和访问任何关联的参数


3.2.1 插件集成方法

1 添加跟 gradle 依赖
def nav_version = "2.3.5"
classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$nav_version"
复制代码


2 app.gradle中加入插件
plugins {
    id 'androidx.navigation.safeargs'
}
复制代码


3.2.2 插件说明(参考官方)

启用 Safe Args 后,生成的代码会为每个操作包含以下类型安全的类和方法,以及每个发送和接收目的地。

  • 为生成操作的每一个目的地创建一个类。该类的名称是在源目的地的名称后面加上“Directions”。例如,如果源目的地是名为 SpecifyAmountFragment 的 Fragment,则生成的类的名称为 SpecifyAmountFragmentDirections。 该类会为源目的地中定义的每个操作提供一个方法。
  • 对于用于传递参数的每个操作,都会创建一个 inner 类,该类的名称根据操作的名称确定。例如,如果操作名称为 confirmationAction,,则类名称为 ConfirmationAction。如果您的操作包含不带 defaultValue 的参数,则您可以使用关联的 action 类来设置参数值。
  • 为接收目的地创建一个类。该类的名称是在目的地的名称后面加上“Args”。例如,如果目的地 Fragment 的名称为 ConfirmationFragment,,则生成的类的名称为 ConfirmationFragmentArgs。可以使用该类的 fromBundle() 方法检索参数。


3.2.3 代码

代码所在分支:deliverparams

1、导航图代码

CFragment 的标签体中的标签就是 CFragment 要接收的数据

<?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/jjj"
    app:startDestination="@id/AFragment">
    <fragment
        android:id="@+id/AFragment"
        android:name="com.mage.navigationdemo.AFragment"
        android:label="fragment_origin"
        tools:layout="@layout/fragment_origin" >
        <action
            android:id="@+id/action_AFragment_to_destiationFragment"
            app:destination="@id/destiationFragment" />
    </fragment>
    <fragment
        android:id="@+id/destiationFragment"
        android:name="com.mage.navigationdemo.BFragment"
        android:label="fragment_destiation"
        tools:layout="@layout/fragment_destiation" />
    <fragment
        android:id="@+id/CFragment"
        android:name="com.mage.navigationdemo.CFragment"
        android:label="fragment_c"
        tools:layout="@layout/fragment_c" >
        <argument
            android:name="data"
            app:argType="string"
            android:defaultValue="1" />
    </fragment>
</navigation>
复制代码


2、源 Fragment 跳转代码

插件会自动生成 CFragmentArgs 参数类

btnTC.setOnClickListener {
            AFragmentDirections.actionAFragmentToDestiationFragment()
            val args = CFragmentArgs.Builder().setData("AFragment传输到CFragment的数据").build().toBundle()
            val findNavController = findNavController()
            findNavController.navigate(R.id.CFragment,args)
        }
复制代码


3、目的地 Fragment 解析参数代码
var cFragmentArgs: CFragmentArgs? = null
    override fun onAttach(context: Context) {
        super.onAttach(context)
        arguments?.let{
            cFragmentArgs = CFragmentArgs.fromBundle(it)
        }
    }
复制代码


4、实现效果

image.png



相关文章
|
9天前
|
编译器 Android开发 开发者
带你了解Android Jetpack库中的依赖注入框架:Hilt
本文介绍了Hilt,这是Google为Android开发的依赖注入框架,基于Dagger构建,旨在简化依赖注入过程。Hilt通过自动化的组件和注解减少了DI的样板代码,提高了应用的可测试性和可维护性。文章详细讲解了Hilt的主要概念、基本用法及原理,帮助开发者更好地理解和应用Hilt。
24 8
|
9天前
|
缓存 搜索推荐 Android开发
安卓应用开发中的自定义View组件实践
【9月更文挑战第10天】在安卓开发领域,自定义View是提升用户体验和实现界面个性化的重要手段。本文将通过一个实际案例,展示如何在安卓项目中创建和使用自定义View组件,包括设计思路、实现步骤以及可能遇到的问题和解决方案。文章不仅提供了代码示例,还深入探讨了自定义View的性能优化技巧,旨在帮助开发者更好地掌握这一技能。
|
28天前
|
编解码 测试技术 Android开发
Android经典实战之用 CameraX 库实现高质量的照片和视频拍摄功能
本文详细介绍了如何利用CameraX库实现高质量的照片及视频拍摄功能,包括添加依赖、初始化、权限请求、配置预览与捕获等关键步骤。此外,还特别针对不同分辨率和帧率的视频拍摄提供了性能优化策略,确保应用既高效又稳定。
62 1
Android经典实战之用 CameraX 库实现高质量的照片和视频拍摄功能
|
11天前
|
安全 Java Android开发
探索安卓应用开发的新趋势:Kotlin和Jetpack Compose
在安卓应用开发领域,随着技术的不断进步,新的编程语言和框架层出不穷。Kotlin作为一种现代的编程语言,因其简洁性和高效性正逐渐取代Java成为安卓开发的首选语言。同时,Jetpack Compose作为一个新的UI工具包,提供了一种声明式的UI设计方法,使得界面编写更加直观和灵活。本文将深入探讨Kotlin和Jetpack Compose的特点、优势以及如何结合使用它们来构建现代化的安卓应用。
26 4
|
22天前
|
存储 搜索推荐 Java
探索安卓开发中的自定义视图:打造个性化UI组件Java中的异常处理:从基础到高级
【8月更文挑战第29天】在安卓应用的海洋中,一个独特的用户界面(UI)能让应用脱颖而出。自定义视图是实现这一目标的强大工具。本文将通过一个简单的自定义计数器视图示例,展示如何从零开始创建一个具有独特风格和功能的安卓UI组件,并讨论在此过程中涉及的设计原则、性能优化和兼容性问题。准备好让你的应用与众不同了吗?让我们开始吧!
|
21天前
|
XML 搜索推荐 Android开发
安卓开发中的自定义View组件实践
【8月更文挑战第30天】探索Android世界,自定义View是提升应用界面的关键。本文以简洁的语言带你了解如何创建自定义View,从基础到高级技巧,一步步打造个性化的UI组件。
|
1月前
|
图形学 Android开发
小功能⭐️Unity调用Android常用事件
小功能⭐️Unity调用Android常用事件
|
29天前
|
开发工具 Android开发
Android项目架构设计问题之组件A通知组件B某个事件的发生如何解决
Android项目架构设计问题之组件A通知组件B某个事件的发生如何解决
28 0
|
2月前
|
机器学习/深度学习 人工智能 算法
探索AI在医疗影像分析中的应用探索安卓开发中的自定义View组件
【7月更文挑战第31天】随着人工智能技术的飞速发展,其在医疗健康领域的应用日益广泛。本文将聚焦于AI技术在医疗影像分析中的运用,探讨其如何通过深度学习模型提高诊断的准确性和效率。我们将介绍一些关键的深度学习算法,并通过实际代码示例展示这些算法是如何应用于医学影像的处理和分析中。文章旨在为读者提供对AI在医疗领域应用的深刻理解和实用知识。
30 0