开发者

Android在kts中使用navigation及Args的方法

目录
  • android在kts中使用navigation及Args
  • 前言:
  • 1.项目依赖导入:
  • 2.app目录的build.gradle配置:
  • 3.项目的build.gradle配置:
  • 4.在布局添加导航组件:
  • 5.Fragment_main布局:
  • 6.Fragmen编程客栈t_mine布局:
  • 7.Fragment_second布局:
  • 8.activity_main主界面:
  • 9.MainActivity代码:
  • 10.MainFragment代码:
  • 11.MineFragment代码:
  • 12.SecondFragment代码:
  • 13.传递参数的方式:
    • 13.1使用bundle:
    • 13.2使用Safs安全方式传递:
  • 14.实现效果如下:
    • 15.项目demo地址:

      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" }

      Android在kts中使用navigation及Args的方法

      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)

      Android在kts中使用navigation及Args的方法

      Android在kts中使用navigation及Args的方法

      3.项目的build.gradle配置:

      plugins {
          alias(libs.plugins.androidApplication) apply false
          alias(libs.plugins.jetbrainsKotlinAndroid) apply false
          alias(libs.plugins.navigation.safe.args) apply false
      }

      Android在kts中使用navigation及Args的方法

      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>

      Android在kts中使用navigation及Args的方法

      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_tjavascriptoEndOf="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)
                  }
              }
          }
      }

      Android在kts中使用navigation及Args的方法

      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(
              inpythonflater: 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.setOnClickListene编程r{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.jsputInt("age", 30)
          Navigation.findNavController(v)
              .navigate(R.id.action_mainFragment_to_secondFragment, bundle)
      })

      Android在kts中使用navigation及Args的方法

      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)
      }

      Android在kts中使用navigation及Args的方法

      14.实现效果如下:

      Android在kts中使用navigation及Args的方法

      Android在kts中使用navigation及Args的方法

      Android在kts中使用navigation及Args的方法

      15.项目demo地址:

      https://gitee.com/jackning_admin/flowbus-demo

      到此这篇关于Android在kts中使用navigation及Args的文章就介绍到这了,更多相关Android 使用navigation Args内容请搜索编程客栈(www.devze.com)以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程客栈(www.devze.com)!

      0

      上一篇:

      下一篇:

      精彩评论

      暂无评论...
      验证码 换一张
      取 消

      最新开发

      开发排行榜