Android在kts中使用navigation及Args的方法
Android在kts中使用navigation及Args
前言:
? 之前在項(xiàng)目中使用過navigation,但都是以Groory的方式,最近一年多使用kts后忍不住把項(xiàng)目都改成kts的方式,不過其中也遇到不少坑,今天就講解一下如何在kts中使用navigation和安全地傳遞參數(shù)Args。
1.項(xiàng)目依賴導(dǎo)入:
在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.項(xiàng)目的build.gradle配置:
plugins {
alias(libs.plugins.androidApplication) apply false
alias(libs.plugins.jetbrainsKotlinAndroid) apply false
alias(libs.plugins.navigation.safe.args) apply false
}
4.在布局添加導(dǎo)航組件:
在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 -> { //數(shù)據(jù)返回
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, "顯示時(shí)間自定的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, "傳遞過來的參數(shù)為 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 的參數(shù)為 name = $name , age = $age")
Log.d(TAG, "姓名:" + name + "年齡:" + age)
}
private fun initView() {
binding.let {
it.tvTitle.text = name
it.tvAge.text = age.toString()
}
}
}13.傳遞參數(shù)的方式:
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.實(shí)現(xiàn)效果如下:



15.項(xiàng)目demo地址:
https://gitee.com/jackning_admin/flowbus-demo
到此這篇關(guān)于Android在kts中使用navigation及Args的文章就介紹到這了,更多相關(guān)Android 使用navigation Args內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
android判斷設(shè)備是否有相機(jī)的實(shí)例代碼
下面小編就為大家?guī)硪黄猘ndroid判斷設(shè)備是否有相機(jī)的實(shí)例代碼。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-03-03
Android屏幕適配工具類 Android自動(dòng)生成不同分辨率的值
這篇文章主要為大家詳細(xì)介紹了Android屏幕適配工具類,Android自動(dòng)生成不同分辨率的值,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-03-03
發(fā)布?Android?library?到?Maven?解析
這篇文章主要介紹了發(fā)布?Android?library到Maven解析,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下2022-09-09
Android studio 廣播的簡(jiǎn)單使用代碼詳解
這篇文章主要介紹了Android studio 廣播的簡(jiǎn)單使用,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-04-04
dialog dismiss時(shí)鍵盤不消失的問題淺析及解決辦法
這篇文章主要介紹了dialog dismiss時(shí)鍵盤不消失的問題淺析及兩種解決方法,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友參考下2017-01-01
Android自定義View實(shí)現(xiàn)帶數(shù)字的進(jìn)度條實(shí)例代碼
這篇文章主要介紹了Android自定義View實(shí)現(xiàn)帶數(shù)字的進(jìn)度條實(shí)例代碼的相關(guān)資料,需要的朋友可以參考下2016-03-03
Android帶數(shù)字或紅點(diǎn)的底部導(dǎo)航攔和聯(lián)網(wǎng)等待加載動(dòng)畫示例
這篇文章主要介紹了Android帶數(shù)字或紅點(diǎn)的底部導(dǎo)航攔和聯(lián)網(wǎng)等待加載動(dòng)畫示例,具有一定的參考價(jià)值,有興趣的同學(xué)可以了解一下。2017-03-03
Android 自定義彈出菜單和對(duì)話框功能實(shí)例代碼
Android 開發(fā)當(dāng)中,可能會(huì)存在許多自定義布局的需求,比如自定義彈出菜單(popupWindow),以及自定義對(duì)話框(Dialog)。下面通過本文給大家介紹Android 自定義彈出菜單和對(duì)話框功能實(shí)例代碼,感興趣的朋友一起看看吧2017-08-08

