android在kts中使用navigation及args
前言:
之前在项目中使用过navigation,但都是以groory的方式,最近一年多使用kts后忍不住把项目都改成kts的方式,不过其中也遇到不少坑,今天就讲解一下如何在kts中使用navigation和安全地传递参数args。
1.项目依赖导入:
在libs.versions.toml文件下添加以下依赖:
navigationfragmentktx = "2.6.0"
navigationuiktx = "2.6.0"
navigation-fragment = {group = "androidx.navigation",name = "navigation-fragment-ktx",version.ref = "navigationfragmentktx"}
navigation-ui = {group = "androidx.navigation",name = "navigation-ui-ktx",version.ref = "navigationuiktx"}
navigation-safe-args = { id = "androidx.navigation.safeargs.kotlin", version = "2.8.0" }
2.app目录的build.gradle配置:
plugins {
alias(libs.plugins.androidapplication)
alias(libs.plugins.jetbrainskotlinandroid)
alias(libs.plugins.navigation.safe.args)
}
implementation(libs.navigation.fragment)
implementation(libs.navigation.ui)

3.项目的build.gradle配置:
plugins {
alias(libs.plugins.androidapplication) apply false
alias(libs.plugins.jetbrainskotlinandroid) apply false
alias(libs.plugins.navigation.safe.args) apply false
}
4.在布局添加导航组件:
在res目录添加navigation——nav_graph文件
<?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/mainfragment">
<fragment
android:id="@+id/mainfragment"
android:label="fragment_main"
android:name="com.cloud.flowbusdemo.fragment.mainfragment"
tools:layout="@layout/fragment_main">
<action
android:id="@+id/action_mainfragment_to_secondfragment"
app:destination="@id/secondfragment"
app:popenteranim="@anim/slide_in_left"
app:popexitanim="@anim/slide_out_right"
app:enteranim="@anim/slide_in_right"
app:exitanim="@anim/slide_out_left"/>
<action
android:id="@+id/action_mainfragment_to_minefragment"
app:destination="@id/minefragment"
app:enteranim="@anim/slide_in_left"
app:exitanim="@anim/slide_in_right"
app:popenteranim="@anim/slide_out_left"
app:popexitanim="@anim/slide_out_right" />
<argument
android:name="name"
app:argtype="string"
android:defaultvalue="xiaozhang"/>
<argument
android:name="age"
app:argtype="integer"
android:defaultvalue="1"/>
</fragment>
<fragment
android:id="@+id/secondfragment"
android:label="fragment_second"
android:name="com.cloud.flowbusdemo.fragment.secondfragment"
tools:layout="@layout/fragment_second"/>
<fragment
android:id="@+id/minefragment"
android:name="com.cloud.flowbusdemo.fragment.minefragment"
android:label="fragment_mine"
tools:layout="@layout/fragment_mine" />
</navigation>
5.fragment_main布局:
fragment_mine.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.constraintlayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<androidx.appcompat.widget.appcompattextview
android:id="@+id/tvtitle"
android:layout_width="0dp"
android:layout_height="40dp"
app:layout_constraintstart_tostartof="parent"
app:layout_constraintend_toendof="parent"
app:layout_constrainttop_totopof="parent"
android:textsize="18sp"
android:textcolor="@color/white"
android:gravity="center"
android:text="mainfragment"
android:layout_margin="20dp"
android:background="@color/design_default_color_primary"
tools:ignore="missingconstraints" />
<androidx.appcompat.widget.appcompattextview
android:id="@+id/btntosecondfragment"
android:layout_width="0dp"
android:layout_height="40dp"
app:layout_constrainttop_tobottomof="@id/tvtitle"
app:layout_constraintstart_tostartof="parent"
app:layout_constraintend_toendof="parent"
android:textallcaps="false"
android:textcolor="@color/white"
android:gravity="center"
android:layout_margin="20dp"
android:background="@color/design_default_color_primary"
android:text="打开secondfragment"/>
<androidx.appcompat.widget.appcompattextview
android:id="@+id/btntominefragment"
android:layout_width="0dp"
android:layout_height="40dp"
app:layout_constrainttop_tobottomof="@+id/btntosecondfragment"
app:layout_constraintstart_tostartof="parent"
app:layout_constraintend_toendof="parent"
android:textallcaps="false"
android:layout_margintop="10dp"
android:textcolor="@color/white"
android:gravity="center"
android:layout_margin="20dp"
android:background="@color/design_default_color_primary"
android:text="打开minefragment"/>
</androidx.constraintlayout.widget.constraintlayout>6.fragment_mine布局:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.constraintlayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto">
<textview
android:id="@+id/tvtitle"
android:layout_width="200dp"
android:layout_height="50dp"
android:textsize="20sp"
tools:text="姓名"
android:gravity="center"
android:background="@color/design_default_color_primary"
app:layout_constrainttop_totopof="parent"
app:layout_constraintstart_tostartof="parent"
app:layout_constraintend_toendof="parent"
android:textcolor="@color/white"
android:layout_margintop="20dp"/>
<textview
android:id="@+id/tvage"
android:layout_width="200dp"
android:layout_height="50dp"
android:textsize="18sp"
tools:text="年龄"
android:gravity="center"
android:background="@color/design_default_color_primary"
app:layout_constraintstart_tostartof="parent"
app:layout_constraintend_toendof="parent"
app:layout_constrainttop_tobottomof="@id/tvtitle"
android:textcolor="@color/white"
android:layout_margintop="20dp"/>
</androidx.constraintlayout.widget.constraintlayout>7.fragment_second布局:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.constraintlayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto">
<textview
android:id="@+id/tvtitle"
android:layout_width="200dp"
android:layout_height="50dp"
android:textsize="20sp"
tools:text="姓名"
android:gravity="center"
android:background="@color/design_default_color_primary"
app:layout_constrainttop_totopof="parent"
app:layout_constraintstart_tostartof="parent"
app:layout_constraintend_toendof="parent"
android:textcolor="@color/white"
android:layout_margintop="20dp"/>
<textview
android:id="@+id/tvage"
android:layout_width="200dp"
android:layout_height="50dp"
android:textsize="18sp"
tools:text="年龄"
android:gravity="center"
android:background="@color/design_default_color_primary"
app:layout_constraintstart_tostartof="parent"
app:layout_constraintend_toendof="parent"
app:layout_constrainttop_tobottomof="@id/tvtitle"
android:textcolor="@color/white"
android:layout_margintop="20dp"/>
</androidx.constraintlayout.widget.constraintlayout>8.activity_main主界面:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.constraintlayout 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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".mainactivity">
<androidx.recyclerview.widget.recyclerview
android:id="@+id/rv_wallpaper"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingstart="2dp"
android:paddingend="2dp"
android:visibility="gone" />
<progressbar
android:id="@+id/pb_loading"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
app:layout_constraintbottom_tobottomof="parent"
app:layout_constraintend_toendof="parent"
app:layout_constraintstart_tostartof="parent"
app:layout_constrainttop_totopof="parent" />
<textview
android:id="@+id/btn_get_wallpaper"
android:layout_width="0dp"
android:layout_height="40dp"
android:text="获取壁纸"
android:textcolor="@color/white"
android:gravity="center"
android:background="@color/design_default_color_primary"
app:layout_constraintend_toendof="parent"
app:layout_constraintstart_tostartof="parent"
app:layout_constrainttop_totopof="parent"
android:layout_margin="20dp"/>
<fragment
android:id="@+id/nav_host_fragment"
android:name="androidx.navigation.fragment.navhostfragment"
android:layout_width="0dp"
android:layout_height="0dp"
app:defaultnavhost="true"
app:layout_constraintbottom_tobottomof="parent"
app:layout_constraintleft_toleftof="parent"
app:layout_constraintright_torightof="parent"
app:layout_constrainttop_tobottomof="@+id/btn_get_wallpaper"
app:navgraph="@navigation/nav_graph"
android:layout_margintop="20dp"/>
</androidx.constraintlayout.widget.constraintlayout>9.mainactivity代码:
package com.cloud.flowbusdemo
import android.annotation.suppresslint
import android.content.intent
import android.os.bundle
import android.util.log
import android.view.view
import android.widget.toast
import androidx.appcompat.app.appcompatactivity
import androidx.lifecycle.viewmodelprovider
import androidx.lifecycle.lifecyclescope
import androidx.recyclerview.widget.gridlayoutmanager
import com.blankj.utilcode.util.logutils
import com.cloud.flowbusdemo.databinding.activitymainbinding
import com.cloud.flowbusdemo.flow.flowbus
import com.cloud.flowbusdemo.http.httputils
import com.cloud.flowbusdemo.intent.mainintent
import com.cloud.flowbusdemo.model.messageevent
import com.cloud.flowbusdemo.service.flowbustestservice
import com.cloud.flowbusdemo.ui.adapter.wallpaperadapter
import com.cloud.flowbusdemo.ui.viewmodel.mainviewmodel
import com.cloud.flowbusdemo.ui.viewmodel.viewmodelfactory
import com.cloud.flowbusdemo.uistate.mainuistate
import com.cloud.flowbusdemo.utils.ctoast
import com.cloud.flowbusdemo.utils.generictoast
import com.cloud.flowbusdemo.utils.singletoast
import kotlinx.coroutines.launch
class mainactivity : appcompatactivity() {
private lateinit var binding: activitymainbinding
private lateinit var mainviewmodel: mainviewmodel
private var wallpaperadapter = wallpaperadapter(arraylistof())
private val tag = "flowbusdemo"
private var mctoast: ctoast? = null
override fun oncreate(savedinstancestate: bundle?) {
super.oncreate(savedinstancestate)
binding = activitymainbinding.inflate(layoutinflater)
setcontentview(binding.root)
mainviewmodel = viewmodelprovider(
this,
viewmodelfactory(httputils.apiservice)
)[mainviewmodel::class.java]
initview()
observeviewmodel()
initservice()
}
private fun initservice() {
val intent = intent(this@mainactivity, flowbustestservice::class.java)
intent.putextra("sockurl","")
startservice(intent)
}
/**
* viewmodel
*/
@suppresslint("notifydatasetchanged")
private fun observeviewmodel() {
lifecyclescope.launch {
mainviewmodel.state.collect {
when (it) {
is mainuistate.idle -> {
}
is mainuistate.loading -> {
binding.btngetwallpaper.visibility = view.gone
binding.pbloading.visibility = view.visible
}
is mainuistate.success -> { //数据返回
binding.btngetwallpaper.visibility = view.gone
binding.pbloading.visibility = view.gone
binding.rvwallpaper.visibility = view.visible
it.wallpaper.let { paper ->
wallpaperadapter.adddata(paper.res.vertical)
}
wallpaperadapter.notifydatasetchanged()
}
is mainuistate.error -> {
binding.pbloading.visibility = view.gone
binding.btngetwallpaper.visibility = view.visible
log.d("tag", "observeviewmodel: $it.error")
toast.maketext(this@mainactivity, it.error, toast.length_long).show()
}
}
}
}
}
/**
* 初始化
*/
private fun initview() {
binding.rvwallpaper.apply {
layoutmanager = gridlayoutmanager(this@mainactivity, 2)
adapter = wallpaperadapter
}
binding.btngetwallpaper.setonclicklistener {
lifecyclescope.launch {
mainviewmodel.mainintentchannel.send(mainintent.getwallpaper)
}
val intent = intent(this@mainactivity,testactivity::class.java)
startactivity(intent)
val timetoast =
singletoast.maketext(this@mainactivity, "显示时间自定的toast", 10.0)
timetoast.show()
}
flowbus.with<messageevent>("test").register(this@mainactivity) {
logutils.d(tag,it.tostring())
if(it.message == "stop"){
logutils.d(tag,"===接收到的消息为==="+it.message)
}
}
flowbus.with<messageevent>("minefragment").register(this@mainactivity) {
logutils.d(tag,it.tostring())
if(it.message == "onmine"){
logutils.d(tag,"===接收到的消息为1111==="+it.message)
}
}
}
}
10.mainfragment代码:
package com.cloud.flowbusdemo.fragment
import android.os.bundle
import android.view.layoutinflater
import android.view.view
import android.view.viewgroup
import androidx.fragment.app.fragment
import androidx.navigation.navigation
import com.cloud.flowbusdemo.r
import com.cloud.flowbusdemo.databinding.fragmentmainbinding
private const val arg_param_name = "name"
private const val arg_param_age = "age"
/**
* @auth: njb
* @date: 2024/9/17 18:46
* @desc: 描述
*/
class mainfragment : fragment() {
private lateinit var binding: fragmentmainbinding
private var name: string? = null
private var age: int? = null
override fun oncreate(savedinstancestate: bundle?) {
super.oncreate(savedinstancestate)
arguments?.let {
name = it.getstring(arg_param_name)
age = it.getint(arg_param_age)
}
}
override fun oncreateview(
inflater: layoutinflater,
container: viewgroup?,
savedinstancestate: bundle?
): view {
binding = fragmentmainbinding.inflate(layoutinflater)
initview()
return binding.root
}
private fun initview() {
binding.btntosecondfragment.setonclicklistener(view.onclicklistener { v ->
/* val bundle = bundle()
bundle.putstring("name", "michael")
bundle.putint("age", 30)*/
val args: bundle = bundle().apply {
this.putstring(arg_param_name, "哈哈")
this.putint(arg_param_age, 25)
}
navigation.findnavcontroller(v)
.navigate(r.id.action_mainfragment_to_secondfragment, args)
})
binding.btntominefragment.setonclicklistener{v ->
val args: bundle = bundle().apply {
this.putstring(arg_param_name, "tom")
this.putint(arg_param_age, 18)
}
val navcontroller = navigation.findnavcontroller(v)
//navcontroller.navigate(r.id.action_mainfragment_to_minefragment, args)
val bundle: bundle = mainfragmentargs("haha",20).tobundle()
navigation.findnavcontroller(v).navigate(r.id.action_mainfragment_to_minefragment,bundle)
}
}
}11.minefragment代码:
package com.cloud.flowbusdemo.fragment
import android.os.bundle
import android.util.log
import android.view.layoutinflater
import android.view.view
import android.view.viewgroup
import androidx.fragment.app.fragment
import androidx.lifecycle.lifecyclescope
import androidx.navigation.fragment.navargs
import com.cloud.flowbusdemo.databinding.fragmentminebinding
import com.cloud.flowbusdemo.flow.flowbus
import com.cloud.flowbusdemo.model.messageevent
import kotlinx.coroutines.launch
private const val arg_param_name = "name"
private const val arg_param_age = "age"
/**
* @auth: njb
* @date: 2024/9/17 19:43
* @desc: 描述
*/
class minefragment :fragment(){
private lateinit var binding: fragmentminebinding
private val tag = "minefragment"
private var name: string? = null
private var age: int? = 0
private val args:mainfragmentargs by navargs()
override fun oncreate(savedinstancestate: bundle?) {
super.oncreate(savedinstancestate)
args.let {
name = args.name
age = args.age
}
log.i(tag, "传递过来的参数为 name = $name , age = $age")
log.d(tag, "姓名:" + name + "年龄:" + age)
}
override fun oncreateview(
inflater: layoutinflater,
container: viewgroup?,
savedinstancestate: bundle?
): view {
binding = fragmentminebinding.inflate(layoutinflater)
initview()
return binding.root
}
private fun initview() {
val messageevent = messageevent()
messageevent.message = "onmine"
messageevent.state = false
binding.let {
it.tvtitle.text = name
it.tvage.text = age.tostring()
it.tvtitle.setonclicklistener {
lifecyclescope.launch {
flowbus.with<messageevent>("minefragment").post(this, messageevent)
}
}
}
}
}12.secondfragment代码:
package com.cloud.flowbusdemo.fragment
import android.os.bundle
import android.util.log
import android.view.layoutinflater
import android.view.view
import android.view.viewgroup
import androidx.fragment.app.fragment
import androidx.lifecycle.lifecyclescope
import com.cloud.flowbusdemo.constants.constants
import com.cloud.flowbusdemo.databinding.fragmentminebinding
import com.cloud.flowbusdemo.databinding.fragmentsecondbinding
import com.cloud.flowbusdemo.flow.flowbus
import com.cloud.flowbusdemo.model.messageevent
import kotlinx.coroutines.launch
/**
* @auth: njb
* @date: 2024/9/17 18:48
* @desc: 描述
*/
class secondfragment : fragment(){
private val tag = "secondfragment"
private var name: string? = null
private var age: int? = null
private lateinit var binding: fragmentsecondbinding
override fun oncreateview(
inflater: layoutinflater,
container: viewgroup?,
savedinstancestate: bundle?
): view {
binding = fragmentsecondbinding.inflate(layoutinflater)
initview()
return binding.root
}
override fun oncreate(savedinstancestate: bundle?) {
super.oncreate(savedinstancestate)
arguments?.let {
name = it.getstring(constants.arg_param_name)
age = it.getint(constants.arg_param_age)
}
log.i(tag, "mainfragment 传递到 secondfragment 的参数为 name = $name , age = $age")
log.d(tag, "姓名:" + name + "年龄:" + age)
}
private fun initview() {
binding.let {
it.tvtitle.text = name
it.tvage.text = age.tostring()
}
}
}13.传递参数的方式:
13.1使用bundle:
binding.btntosecondfragment.setonclicklistener(view.onclicklistener { v ->
val bundle = bundle()
bundle.putstring("name", "michael")
bundle.putint("age", 30)
navigation.findnavcontroller(v)
.navigate(r.id.action_mainfragment_to_secondfragment, bundle)
})
13.2使用safs安全方式传递:
binding.btntominefragment.setonclicklistener{v ->
val bundle: bundle = mainfragmentargs("haha",20).tobundle()
navigation.findnavcontroller(v).navigate(r.id.action_mainfragment_to_minefragment,bundle)
}
14.实现效果如下:



15.项目demo地址:
https://gitee.com/jackning_admin/flowbus-demo
到此这篇关于android在kts中使用navigation及args的文章就介绍到这了,更多相关android 使用navigation args内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论