郑州网站建设zzmshl,seo关键词优化公司官网,360优化大师最新版下载,做游戏网站的前景文章目录 一、页面跳转间的传统的数据传递方式1、传统的数据传递方式 - Bundle 传递数据1、Navigation 组件中的 Bundle 数据传递2、传统数据传递实现步骤3、FragmentA 完整代码示例4、FragmentB 完整代码示例5、执行结果 2、使用 Bundle 传递数据安全性差 二、页面跳转间的传统… 文章目录 一、页面跳转间的传统的数据传递方式1、传统的数据传递方式 - Bundle 传递数据1、Navigation 组件中的 Bundle 数据传递2、传统数据传递实现步骤3、FragmentA 完整代码示例4、FragmentB 完整代码示例5、执行结果 2、使用 Bundle 传递数据安全性差 二、页面跳转间的传统的数据传递方式1、导入插件依赖2、使用插件3、在 navigation_graph.xml 中定义要传递的 argument 参数信息4、重新编译生成参数传递相关代码5、调用 FragmentBArgs 类生成参数 Bundle6、FragmentA 中获取参数 三、两种传参方式的完整代码示例1、Gradle 构建脚本I、根目录下 settings.gradle 构建脚本II、根目录下 build.gradle 构建脚本III、Module 目录下 build.gradle 构建脚本 2、res 资源配置I、MainActivity 页面布局II、FragmentA 页面布局III、FragmentB 页面布局IV、navigation_graph.xml 配置 3、页面相关 Kotlin 代码I、MainActivity 页面代码II、FragmentA 页面代码III、FragmentB 页面代码 4、执行结果 代码地址 :
CSDN ( 本博客代码快照 | 推荐下载 0 积分 ) : https://download.csdn.net/download/han1202012/88251933GitHub ( 可能已经覆盖 ) : https://github.com/han1202012/Navigation 一、页面跳转间的传统的数据传递方式 1、传统的数据传递方式 - Bundle 传递数据 1、Navigation 组件中的 Bundle 数据传递 之前的 默认 Navigation 跳转方法 , 只需要传入 navigation 资源 ID , 即可完成页面跳转 ;
public open fun navigate(IdRes resId: Int)Navigation 机制中 , 还提供了可以传入 Bundle 参数的跳转方法 , 调用该方法 , 可以在页面跳转时 , 传递一个 Bundle 参数 , 其中可以封装一系列的参数键值对 ;
public open fun navigate(IdRes resId: Int, args: Bundle?)2、传统数据传递实现步骤 首先 , 创建 Bundle 实例对象 , 向其中封装 “NAME” “Tom” , “AGE” 18 , 两组数据 ;
// 定义 Kotlin 常量
private const val ARG_PARAM_NAME NAME
private const val ARG_PARAM_AGE AGE// 正常方式传递参数
var args: Bundle Bundle().apply {// 设置 Bundle 对象参数数据this.putString(ARG_PARAM_NAME, Tom)this.putInt(ARG_PARAM_AGE, 18)
}然后 , 调用 Navigation#findNavController 函数 , 获取 NavigationController ;
// 获取 NavigationController
val navController Navigation.findNavController(it)
// 按照 action_fragmentA_to_fragmentB 对应的 action 的导航路线走
navController.navigate(R.id.action_fragmentA_to_fragmentB, args)再后 , 调用 NavigationController#navigate 方法 , 传入对应的 Navigation 导航资源 和 要传递的 Bundle 参数 ;
// 按照 action_fragmentA_to_fragmentB 对应的 action 的导航路线走
navController.navigate(R.id.action_fragmentA_to_fragmentB, args)最后 , 在跳转后的界面中 , 调用 getArguments 函数 , 并获取 NAME 和 AGE 对应的参数值 ;
// 定义 Kotlin 常量
private const val ARG_PARAM_NAME NAME
private const val ARG_PARAM_AGE AGEarguments?.let {name it.getString(ARG_PARAM_NAME)age it.getInt(ARG_PARAM_AGE)
}3、FragmentA 完整代码示例 FragmentA 完整代码示例 :
package kim.hsl.navimport android.os.Bundle
import android.util.Log
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import androidx.navigation.Navigation// 定义 Kotlin 常量
private const val ARG_PARAM_NAME NAME
private const val ARG_PARAM_AGE AGEclass FragmentB : Fragment() {private var name: String? nullprivate var age: Int? nulloverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)arguments?.let {name it.getString(ARG_PARAM_NAME)age it.getInt(ARG_PARAM_AGE)}Log.i(TAG, FragmentA 传递到 FragmentB 的参数为 name $name , age $age)}override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,savedInstanceState: Bundle?): View? {// 设置 Fragment 布局文件return inflater.inflate(R.layout.fragment_b, container, false)}override fun onViewCreated(view: View, savedInstanceState: Bundle?) {super.onViewCreated(view, savedInstanceState)val button view.findViewByIdButton(R.id.button)button.setOnClickListener {// 获取 NavigationControllerval navController Navigation.findNavController(it)// 按照 action_fragmentB_to_fragmentA 对应的 action 的导航路线走navController.navigate(R.id.action_fragmentB_to_fragmentA)}}
}4、FragmentB 完整代码示例 FragmentB 完整代码示例 :
package kim.hsl.navimport android.os.Bundle
import android.util.Log
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import androidx.navigation.Navigation// 定义 Kotlin 常量
private const val ARG_PARAM_NAME NAME
private const val ARG_PARAM_AGE AGEclass FragmentB : Fragment() {private var name: String? nullprivate var age: Int? nulloverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)arguments?.let {name it.getString(ARG_PARAM_NAME)age it.getInt(ARG_PARAM_AGE)}Log.i(TAG, FragmentA 传递到 FragmentB 的参数为 name $name , age $age)}override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,savedInstanceState: Bundle?): View? {// 设置 Fragment 布局文件return inflater.inflate(R.layout.fragment_b, container, false)}override fun onViewCreated(view: View, savedInstanceState: Bundle?) {super.onViewCreated(view, savedInstanceState)val button view.findViewByIdButton(R.id.button)button.setOnClickListener {// 获取 NavigationControllerval navController Navigation.findNavController(it)// 按照 action_fragmentB_to_fragmentA 对应的 action 的导航路线走navController.navigate(R.id.action_fragmentB_to_fragmentA)}}
}5、执行结果 运行应用 , 进入界面后 , 自动进入 默认的 FragmentA 界面 , 点击 跳转到 B , 此时 , 跳转到 FragmentB 界面 :
此时 Logcat 日志面板 , 输出如下内容 :
kim.hsl.nav I/TAG: FragmentA 传递到 FragmentB 的参数为 name Tom , age 182、使用 Bundle 传递数据安全性差 使用 传统的方式 , 在 Fragment 之间 传递 数据 , 类型很不安全 ,
设置 传递的数据时 , 需要设置 放入的 数据类型 , 如下代码所示 :
// 正常方式传递参数
var args: Bundle Bundle().apply {// 设置 Bundle 对象参数数据this.putString(NAME, Tom)this.putInt(AGE, 18)
}上面的代码中 , 向 Bundle 中设置了如下两个数据 :
设置了 String 类型的数据 , 名称是 “NAME” 字符串常量 , 值为 字符串 “Tom” ,设置了 Int 类型的数据 , 名称是 “AGE” 字符串常量 , 值为 整型 18 ; 这里要注意 , 设置的时候 , 设置的 NAME 属性值是 String 类型的 , 那么在 FragmentB 中获取的 NAME 属性值也必须是 String 类型的 ,
arguments?.let {name it.getString(NAME)
}此处 没有 类型检查 , 即使你写错了具体的 属性值 名称 和 属性值 类型 , 编译器也不会报错 , 但是在执行时 , 会出现错误 ;
下面的代码中 , 调用 getInt(“Name”) 也不会报错 ; 上面的 使用 Bundle 在 Fragment 之间传递 参数 , 没有类型检查 , 即使写错了数据类型 也不会报错 , 这就导致了 数据传递 不安全 的问题 , 如果出现问题 , 导致错误很难排查 ; 二、页面跳转间的传统的数据传递方式 1、导入插件依赖 安全参数传递需要使用到 androidx.navigation:navigation-safe-args-gradle-plugin:2.3.0-alpha06 中的 androidx.navigation.safeargs 插件 ;
由于在最新版的 Gradle 配置中 , 使用 根目录下 build.gradle 构建脚本中的 直接配置 plugins 插件的方式 , 无法获取到该 androidx.navigation.safeargs 插件 , 因此放弃该方案 , 将 该脚本的 整个 plugins 代码块完全注释掉 ;
plugins {id com.android.application version 7.3.1 apply falseid com.android.library version 7.3.1 apply falseid org.jetbrains.kotlin.android version 1.7.20 apply falseid androidx.navigation.safeargs version 2.3.0-alpha06 apply false
}在 settings.gradle 中 , 使用传统的方式配置 Gralde 编译过程中使用到的插件 ;
下面的章节中 , 可以查看该 settings.gradle 配置的完整源码 ; 配置如下 :
buildscript {repositories {google()mavenCentral()jcenter()maven {url https://maven.aliyun.com/repository/public/}maven{url https://maven.aliyun.com/repository/google/}}dependencies {classpath com.android.tools.build:gradle:7.3.1classpath androidx.navigation:navigation-safe-args-gradle-plugin:2.3.0-alpha06classpath org.jetbrains.kotlin:kotlin-gradle-plugin:1.7.20// NOTE: Do not place your application dependencies here; they belong// in the individual module build.gradle files}
}2、使用插件 在 Module 下的 build.gradle 中 , 使用 androidx.navigation.safeargs 依赖 ;
plugins {id com.android.applicationid org.jetbrains.kotlin.androidid androidx.navigation.safeargs
}3、在 navigation_graph.xml 中定义要传递的 argument 参数信息 如果要从 FragmentB 跳转到 FragmentA 页面时 , 传递数据 , 就将参数信息设置在该 FragmentB 对应的配置文件中 ; 参数格式为 : argumentandroid:nameNAMEapp:argTypestringandroid:defaultValueJerry/参数名称为 NAME ;参数类型是 string 类型 ;参数默认值是 “Jerry” ; 完整的参数配置如下 : fragmentandroid:idid/fragmentBandroid:namekim.hsl.nav.FragmentBandroid:labelfragment_btools:layoutlayout/fragment_b actionandroid:idid/action_fragmentB_to_fragmentAapp:destinationid/fragmentAapp:enterAnimanim/nav_default_enter_animapp:exitAnimanim/nav_default_exit_anim /!-- 配置完毕后 菜单栏/Build/Make 编译一下,自动生成 FragmentBArgs.java 代码, 之后调用该自动生成的类传参 --argumentandroid:nameNAMEapp:argTypestringandroid:defaultValueJerry/argumentandroid:nameAGEapp:argTypeintegerandroid:defaultValue12//fragment4、重新编译生成参数传递相关代码 FragmentB 中 配置完毕 参数相关配置 后 , 选择 菜单栏 / Build / Make 选项 , 重新编译一下,
目的是为了 生成 FragmentBArgs.java 代码, 之后调用该自动生成的类 进行 传参 ; 生成的类在 Navigation\app\build\generated\source\navigation-args\debug\kim\hsl\nav 目录下 , 生成的 FragmentBArgs.java 代码如下 : ( 仅做参考 )
package kim.hsl.nav;import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.navigation.NavArgs;
import java.lang.IllegalArgumentException;
import java.lang.Object;
import java.lang.Override;
import java.lang.String;
import java.lang.SuppressWarnings;
import java.util.HashMap;public class FragmentBArgs implements NavArgs {private final HashMap arguments new HashMap();private FragmentBArgs() {}private FragmentBArgs(HashMap argumentsMap) {this.arguments.putAll(argumentsMap);}NonNullSuppressWarnings(unchecked)public static FragmentBArgs fromBundle(NonNull Bundle bundle) {FragmentBArgs __result new FragmentBArgs();bundle.setClassLoader(FragmentBArgs.class.getClassLoader());if (bundle.containsKey(NAME)) {String NAME;NAME bundle.getString(NAME);if (NAME null) {throw new IllegalArgumentException(Argument \NAME\ is marked as non-null but was passed a null value.);}__result.arguments.put(NAME, NAME);} else {__result.arguments.put(NAME, Jerry);}if (bundle.containsKey(AGE)) {int AGE;AGE bundle.getInt(AGE);__result.arguments.put(AGE, AGE);} else {__result.arguments.put(AGE, 12);}return __result;}SuppressWarnings(unchecked)NonNullpublic String getNAME() {return (String) arguments.get(NAME);}SuppressWarnings(unchecked)public int getAGE() {return (int) arguments.get(AGE);}SuppressWarnings(unchecked)NonNullpublic Bundle toBundle() {Bundle __result new Bundle();if (arguments.containsKey(NAME)) {String NAME (String) arguments.get(NAME);__result.putString(NAME, NAME);} else {__result.putString(NAME, Jerry);}if (arguments.containsKey(AGE)) {int AGE (int) arguments.get(AGE);__result.putInt(AGE, AGE);} else {__result.putInt(AGE, 12);}return __result;}Overridepublic boolean equals(Object object) {if (this object) {return true;}if (object null || getClass() ! object.getClass()) {return false;}FragmentBArgs that (FragmentBArgs) object;if (arguments.containsKey(NAME) ! that.arguments.containsKey(NAME)) {return false;}if (getNAME() ! null ? !getNAME().equals(that.getNAME()) : that.getNAME() ! null) {return false;}if (arguments.containsKey(AGE) ! that.arguments.containsKey(AGE)) {return false;}if (getAGE() ! that.getAGE()) {return false;}return true;}Overridepublic int hashCode() {int result 1;result 31 * result (getNAME() ! null ? getNAME().hashCode() : 0);result 31 * result getAGE();return result;}Overridepublic String toString() {return FragmentBArgs{ NAME getNAME() , AGE getAGE() };}public static class Builder {private final HashMap arguments new HashMap();public Builder(FragmentBArgs original) {this.arguments.putAll(original.arguments);}public Builder() {}NonNullpublic FragmentBArgs build() {FragmentBArgs result new FragmentBArgs(arguments);return result;}NonNullpublic Builder setNAME(NonNull String NAME) {if (NAME null) {throw new IllegalArgumentException(Argument \NAME\ is marked as non-null but was passed a null value.);}this.arguments.put(NAME, NAME);return this;}NonNullpublic Builder setAGE(int AGE) {this.arguments.put(AGE, AGE);return this;}SuppressWarnings(unchecked)NonNullpublic String getNAME() {return (String) arguments.get(NAME);}SuppressWarnings(unchecked)public int getAGE() {return (int) arguments.get(AGE);}}
}5、调用 FragmentBArgs 类生成参数 Bundle 在 FragmentB 中 ,
首先 , 调用 FragmentBArgs#Builder() , 创建 参数创建者类 ,
然后 , 调用 setNAME 和 setAGE 分别设置 参数 ,
再后 , 调用 FragmentBArgs.Builder#build() 函数 , 创建 FragmentBArgs 类型的 参数对象 ,
最后 , 调用 FragmentBArgs#toBundle() 函数 , 将 FragmentBArgs 对象转为 Bundle 类型对象 ; var args: Bundle FragmentBArgs.Builder().setNAME(Trump).setAGE(80).build().toBundle()创建完 Bundle 对象之后 , 将其传给 NavigationController#navigate 函数 , 进行页面跳转 ;
var args: Bundle FragmentBArgs.Builder().setNAME(Trump).setAGE(80).build().toBundle()
// 获取 NavigationController
val navController Navigation.findNavController(it)
// 按照 action_fragmentB_to_fragmentA 对应的 action 的导航路线走
navController.navigate(R.id.action_fragmentB_to_fragmentA, args)后续章节可以查看 FragmentB 的完整代码 ; 6、FragmentA 中获取参数 在 FragmentA 中 , 调用 getArguments 函数 , 获取页面跳转传递的 Bundle 对象即可 ; arguments?.let {name it.getString(ARG_PARAM_NAME)age it.getInt(ARG_PARAM_AGE)}Log.i(TAG, FragmentB 传递到 FragmentA 的参数为 name $name , age $age)三、两种传参方式的完整代码示例 1、Gradle 构建脚本 I、根目录下 settings.gradle 构建脚本 该构建脚本中 , pluginManagement 是最新的 Gradle 配置 , 但是本项目中没有启用 , 注释掉也可以运行 ;
buildscript 是老版本的 Gradle 编译时依赖配置 , 由于本次使用了 androidx.navigation.safeargs 插件 , 该依赖使用新方式配置无法成功下载 , 这里直接使用老的配置方式 ;
dependencyResolutionManagement 中配置的是依赖库的下载地址 ; settings.gradle 构建脚本代码示例 :
pluginManagement {repositories {gradlePluginPortal()google()mavenCentral()jcenter()maven {url https://maven.aliyun.com/repository/public/}maven{url https://maven.aliyun.com/repository/google/}}
}buildscript {repositories {google()mavenCentral()jcenter()maven {url https://maven.aliyun.com/repository/public/}maven{url https://maven.aliyun.com/repository/google/}}dependencies {classpath com.android.tools.build:gradle:7.3.1classpath androidx.navigation:navigation-safe-args-gradle-plugin:2.3.0-alpha06classpath org.jetbrains.kotlin:kotlin-gradle-plugin:1.7.20// NOTE: Do not place your application dependencies here; they belong// in the individual module build.gradle files}
}dependencyResolutionManagement {repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)repositories {google()mavenCentral()}
}
rootProject.name Navigation
include :appII、根目录下 build.gradle 构建脚本 这是新的 Gradle 语法配置 , 需要结合 pluginManagement 配置使用 , 由于下面的配置无法成功下载 androidx.navigation.safeargs 依赖 , 整体作废 ; 根目录下 build.gradle 构建脚本 :
// Top-level build file where you can add configuration options common to all sub-projects/modules.
/*plugins {id com.android.application version 7.3.1 apply falseid com.android.library version 7.3.1 apply falseid org.jetbrains.kotlin.android version 1.7.20 apply falseid androidx.navigation.safeargs version 2.3.0-alpha06 apply false
}*/III、Module 目录下 build.gradle 构建脚本 该配置没有需要注意的 , 导入 androidx.navigation.safeargs 插件就行 ; Module 目录下 build.gradle 构建脚本 :
plugins {id com.android.applicationid org.jetbrains.kotlin.androidid androidx.navigation.safeargs
}android {namespace kim.hsl.navcompileSdk 32defaultConfig {applicationId kim.hsl.navminSdk 21targetSdk 32versionCode 1versionName 1.0testInstrumentationRunner androidx.test.runner.AndroidJUnitRunner}buildTypes {release {minifyEnabled falseproguardFiles getDefaultProguardFile(proguard-android-optimize.txt), proguard-rules.pro}}compileOptions {sourceCompatibility JavaVersion.VERSION_1_8targetCompatibility JavaVersion.VERSION_1_8}kotlinOptions {jvmTarget 1.8}
}dependencies {implementation androidx.core:core-ktx:1.7.0implementation androidx.appcompat:appcompat:1.4.1implementation com.google.android.material:material:1.5.0implementation androidx.constraintlayout:constraintlayout:2.1.3implementation androidx.navigation:navigation-fragment-ktx:2.4.1implementation androidx.navigation:navigation-ui-ktx:2.4.1testImplementation junit:junit:4.13.2androidTestImplementation androidx.test.ext:junit:1.1.3androidTestImplementation androidx.test.espresso:espresso-core:3.4.0
}2、res 资源配置 Resources 资源配置 , 主要是配置 Navigation 相关的 NavigationGraph ; I、MainActivity 页面布局 这是 主页面 Launcher Activity 的布局 , 之后的 Fragment 的 布局 就替换到 fragment 标签位置 ; MainActivity 页面布局 :
?xml version1.0 encodingutf-8?
androidx.constraintlayout.widget.ConstraintLayout xmlns:androidhttp://schemas.android.com/apk/res/androidxmlns:apphttp://schemas.android.com/apk/res-autoxmlns:toolshttp://schemas.android.com/toolsandroid:layout_widthmatch_parentandroid:layout_heightmatch_parenttools:context.MainActivityTextViewandroid:idid/textViewandroid:layout_widthwrap_contentandroid:layout_heightwrap_contentandroid:textHello World!app:layout_constraintBottom_toBottomOfparentapp:layout_constraintEnd_toEndOfparentapp:layout_constraintStart_toStartOfparentapp:layout_constraintTop_toTopOfparent /fragmentandroid:idid/fragmentandroid:nameandroidx.navigation.fragment.NavHostFragmentandroid:layout_widthmatch_parentandroid:layout_heightmatch_parentapp:defaultNavHosttrueapp:navGraphnavigation/navigation_graph //androidx.constraintlayout.widget.ConstraintLayoutII、FragmentA 页面布局 页面布局就是一个简单的 FrameLayout 布局 , 要先创建 Fragment 布局 , 然后才能在 navigation_graph.xml 配置该布局 ; FragmentA 页面布局 :
?xml version1.0 encodingutf-8?
FrameLayout xmlns:androidhttp://schemas.android.com/apk/res/androidxmlns:toolshttp://schemas.android.com/toolsandroid:layout_widthmatch_parentandroid:layout_heightmatch_parenttools:context.FragmentA!-- TODO: Update blank fragment layout --TextViewandroid:layout_widthmatch_parentandroid:layout_heightmatch_parentandroid:textstring/hello_blank_fragment /Buttonandroid:idid/buttonandroid:layout_widthwrap_contentandroid:layout_heightwrap_contentandroid:layout_gravitycenterandroid:text跳转到 Bandroid:onClickonClick //FrameLayoutIII、FragmentB 页面布局 页面布局就是一个简单的 FrameLayout 布局 , 要先创建 Fragment 布局 , 然后才能在 navigation_graph.xml 配置该布局 ; FragmentB 页面布局 :
?xml version1.0 encodingutf-8?
FrameLayout xmlns:androidhttp://schemas.android.com/apk/res/androidxmlns:toolshttp://schemas.android.com/toolsandroid:layout_widthmatch_parentandroid:layout_heightmatch_parenttools:context.FragmentB!-- TODO: Update blank fragment layout --TextViewandroid:layout_widthmatch_parentandroid:layout_heightmatch_parentandroid:textstring/hello_blank_fragment /Buttonandroid:idid/buttonandroid:layout_widthwrap_contentandroid:layout_heightwrap_contentandroid:layout_gravitycenterandroid:text跳转到 Aandroid:onClickonClick //FrameLayoutIV、navigation_graph.xml 配置 在 res 目录下 , 创建 navigation 目录 , 然后在该目录中创建 navigation_graph.xml 配置文件 , 用于配置 页面跳转 相关参数 ;
具体的参数含义 , 可以参考之前的博客 ; navigation_graph.xml 配置 :
?xml version1.0 encodingutf-8?
navigation xmlns:androidhttp://schemas.android.com/apk/res/androidxmlns:apphttp://schemas.android.com/apk/res-autoxmlns:toolshttp://schemas.android.com/toolsandroid:idid/navigation_graphapp:startDestinationid/fragmentAfragmentandroid:idid/fragmentAandroid:namekim.hsl.nav.FragmentAandroid:labelfragment_atools:layoutlayout/fragment_a actionandroid:idid/action_fragmentA_to_fragmentBapp:destinationid/fragmentBapp:enterAnimanim/nav_default_enter_animapp:exitAnimanim/nav_default_exit_anim //fragmentfragmentandroid:idid/fragmentBandroid:namekim.hsl.nav.FragmentBandroid:labelfragment_btools:layoutlayout/fragment_b actionandroid:idid/action_fragmentB_to_fragmentAapp:destinationid/fragmentAapp:enterAnimanim/nav_default_enter_animapp:exitAnimanim/nav_default_exit_anim /!-- 配置完毕后 菜单栏/Build/Make 编译一下,自动生成 FragmentBArgs.java 代码, 之后调用该自动生成的类传参 --argumentandroid:nameNAMEapp:argTypestringandroid:defaultValueJerry/argumentandroid:nameAGEapp:argTypeintegerandroid:defaultValue12//fragment
/navigation3、页面相关 Kotlin 代码 主要是 Activity 和 Fragment 代码 ; I、MainActivity 页面代码 这是主页面 , 复杂使用 Navigation 添加 Fragment ;
package kim.hsl.navimport android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.navigation.Navigation.findNavController
import androidx.navigation.ui.NavigationUIclass MainActivity : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)// fragmentContainerView 组件的 管理 操作通过 NavController 完成// 对应的就是 navController 实例变量val navController findNavController(this, R.id.fragment)NavigationUI.setupActionBarWithNavController(this, navController)}
}II、FragmentA 页面代码 FragmentA 跳转到 FragmentB 使用传统的方式传递参数 , 类型不安全 ; FragmentA 页面代码 :
package kim.hsl.navimport android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import androidx.fragment.app.Fragment
import androidx.navigation.Navigation// 定义 Kotlin 常量
private const val ARG_PARAM_NAME NAME
private const val ARG_PARAM_AGE AGEclass FragmentA : Fragment() {private var name: String? nullprivate var age: Int? nulloverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)arguments?.let {name it.getString(ARG_PARAM_NAME)age it.getInt(ARG_PARAM_AGE)}Log.i(TAG, FragmentB 传递到 FragmentA 的参数为 name $name , age $age)}override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,savedInstanceState: Bundle?): View? {// 设置 Fragment 布局文件return inflater.inflate(R.layout.fragment_a, container, false)}override fun onViewCreated(view: View, savedInstanceState: Bundle?) {super.onViewCreated(view, savedInstanceState)val button view.findViewByIdButton(R.id.button)button.setOnClickListener {// 正常方式传递参数var args: Bundle Bundle().apply {// 设置 Bundle 对象参数数据this.putString(ARG_PARAM_NAME, Tom)this.putInt(ARG_PARAM_AGE, 18)}// 获取 NavigationControllerval navController Navigation.findNavController(it)// 按照 action_fragmentA_to_fragmentB 对应的 action 的导航路线走navController.navigate(R.id.action_fragmentA_to_fragmentB, args)}}
}III、FragmentB 页面代码 FragmentB 跳转到 FragmentA 使用安全方式传递参数 ; FragmentB 页面代码 :
package kim.hsl.navimport android.os.Bundle
import android.util.Log
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import androidx.navigation.Navigation// 定义 Kotlin 常量
private const val ARG_PARAM_NAME NAME
private const val ARG_PARAM_AGE AGEclass FragmentB : Fragment() {private var name: String? nullprivate var age: Int? nulloverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)arguments?.let {name it.getString(ARG_PARAM_NAME)age it.getInt(ARG_PARAM_AGE)}Log.i(TAG, FragmentA 传递到 FragmentB 的参数为 name $name , age $age)}override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,savedInstanceState: Bundle?): View? {// 设置 Fragment 布局文件return inflater.inflate(R.layout.fragment_b, container, false)}override fun onViewCreated(view: View, savedInstanceState: Bundle?) {super.onViewCreated(view, savedInstanceState)val button view.findViewByIdButton(R.id.button)button.setOnClickListener {var args: Bundle FragmentBArgs.Builder().setNAME(Trump).setAGE(80).build().toBundle()// 获取 NavigationControllerval navController Navigation.findNavController(it)// 按照 action_fragmentB_to_fragmentA 对应的 action 的导航路线走navController.navigate(R.id.action_fragmentB_to_fragmentA, args)}}
}4、执行结果 编译运行程序 , 进入默认 Launcher 界面 , 默认显示 FragmentA 页面 , 点击 跳转到 B 按钮 , 此时跳转到了 FragmentB , 使用传统方式传递的参数也能正常获取 ,
kim.hsl.nav I/TAG: FragmentA 传递到 FragmentB 的参数为 name Tom , age 18在 FragmentB 页面点击 跳转到 A 按钮 , 使用安全方式传递的参数 , 也能正常打印出来 ; 代码地址 :
CSDN ( 本博客代码快照 | 推荐下载 0 积分 ) : https://download.csdn.net/download/han1202012/88251933GitHub ( 可能已经覆盖 ) : https://github.com/han1202012/Navigation