Android在kts中使用navigation及Args的方法
Android在kts中使用navigation及Args
前言:
? 之前在項(xiàng)目中使用過(guò)navigation,但都是以Groory的方式,最近一年多使用kts后忍不住把項(xiàng)目都改成kts的方式,不過(guò)其中也遇到不少坑,今天就講解一下如何在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="打開(kāi)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="打開(kāi)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, "傳遞過(guò)來(lái)的參數(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)文章
使用AccessibilityService實(shí)現(xiàn)微信自動(dòng)切換賬號(hào)功能
這篇文章主要為大家詳細(xì)介紹了使用AccessibilityService實(shí)現(xiàn)微信自動(dòng)切換賬號(hào)功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-12-12Android編程之電池電量信息更新的方法(基于BatteryService實(shí)現(xiàn))
這篇文章主要介紹了Android編程之電池電量信息更新的方法,主要基于BatteryService實(shí)現(xiàn)該功能,以實(shí)例形式分析了Android獲取電池電量的具體步驟與實(shí)現(xiàn)技巧,需要的朋友可以參考下2015-11-11android車牌識(shí)別系統(tǒng)EasyPR使用詳解
這篇文章主要為大家詳細(xì)介紹了android車牌識(shí)別系統(tǒng)EasyPR使用,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-12-12輕松實(shí)現(xiàn)Android語(yǔ)音識(shí)別功能
這篇文章主要為初學(xué)者介紹了輕松實(shí)現(xiàn)Android語(yǔ)音識(shí)別功能的代碼,感興趣的小伙伴們可以參考一下2016-07-07在Android中如何使用DataBinding詳解(Kotlin)
這篇文章主要給大家介紹了關(guān)于在Android中如何使用DataBinding(Kotlin)的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-11-11Android自定義控件ViewFipper實(shí)現(xiàn)豎直跑馬燈效果
這篇文章主要為大家詳細(xì)介紹了Android自定義控件ViewFipper實(shí)現(xiàn)豎直跑馬燈效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-12-12Android studio實(shí)現(xiàn)菜單操作
這篇文章主要為大家詳細(xì)介紹了Android studio實(shí)現(xiàn)菜單操作,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-10-10Service與Activity之間的通信(同一進(jìn)程)
這篇文章主要介紹了Service與Activity之間的通信(同一進(jìn)程)的相關(guān)資料,需要的朋友可以參考下2016-03-03