欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Android JetPack之Navigation(三)

程序员文章站 2022-03-13 17:09:23
...

上一节讲述了Navigation的Fragment的切换和回退。本节讲述如何使用Navigation进行Fragment之间的传值问题以及Activity向Fragment传值的问题。主要目的是实现从第一个Fragment向第二个Fragment传递Int类型的参数,第二个Fragment向第三个Fragment传递String类型的参数

Fragment之间的参数传递

在Navigation中对Fragment采用了一种新的传参方式(旧的方式也可以使用)。这一节使用新的传参方式进行编码演示。

添加相关插件依赖

在根项目的build.gradle文件中添加插件依赖:

classpath "android.arch.navigation:navigation-safe-args-gradle-plugin:1.0.0"

在model里面使用这个插件:

apply plugin: 'androidx.navigation.safeargs.kotlin'

开启java8编译

android {
    compileOptions {
        sourceCompatibility = 1.8
        targetCompatibility = 1.8
    }
    kotlinOptions {
        jvmTarget = "1.8"
    }
}

修改navagation资源文件

test_nav.xml

<?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/test_nav"                                                  
app:startDestination="@id/mainPage1Fragment">
 <fragment
 android:id="@+id/mainPage1Fragment" 
 android:name="com.example.test.fragment.MainPage1Fragment"
 android:label="MainPage1Fragment"
 tools:layout="@layout/fragment_item1">
 </fragment>
 <fragment
 android:id="@+id/mainPage2Fragment" 
 android:name="com.example.test.fragment.MainPage2Fragment"
 android:label="MainPage2Fragment"
 tools:layout="@layout/fragment_item2">
 <argument
 android:name="page2"
 app:argType="integer"
 android:defaultValue="10" />
 </fragment>
 <fragment
 android:id="@+id/mainPage3Fragment"
 android:name="com.example.test.fragment.MainPage3Fragment"
 android:label="MainPage3Fragment"
 tools:layout="@layout/fragment_item3">
 <argument
 android:name="page3"
 app:argType="string"
 android:defaultValue="默认值" />
 </fragment>
</navigation>

注意:

  • <argumen/>是Fragment用于传递参数的标签,该标签可以有多个,当多个标签时候,这些参数都需要传递
  • android:name="page2"表示定义的参数的名字
  • app:argType="integer"表示定义参数的类型,具体类型有integerfloatintegerlongbooleanstringreference和序列化的SerializableParcelable以及Enum类型
  • android:defaultValue="10"表示定义参数的默认值

以上内容可以由面板进行操作:
Android JetPack之Navigation(三)

注意:

  • 当面板操作完或者代码编辑完后,需要重新build项目生成相关文件
    Android JetPack之Navigation(三)

修改布局文件

修改fragment_item2.xml和fragment_item3.xml用于展示传递参数的结果:

fragment_item2.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    
 android:orientation="vertical"
 android:layout_width="match_parent"
 android:layout_height="match_parent">
 <androidx.appcompat.widget.AppCompatButton
 android:id="@+id/go"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:text="我是第二个页面,去第三个Fragment"/>
 <androidx.appcompat.widget.AppCompatTextView
 android:id="@+id/content"                                                      
 android:layout_width="wrap_content"                                            
 android:layout_height="wrap_content"/>
</LinearLayout>

fragment_item3.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/item_fragment3">
    <androidx.appcompat.widget.AppCompatButton
        android:id="@+id/go"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="我是第三个页面,去第一个Fragment"/>
    <androidx.appcompat.widget.AppCompatTextView
        android:id="@+id/content"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>
</LinearLayout>

修改Fragment类

MainPage1Fragment.kt

class MainPage1Fragment : Fragment() {
    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                              savedInstanceState: Bundle?): View {
        return inflater.inflate(R.layout.fragment_item1, container, false)
    }

    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)
        go.setOnClickListener {
            val args = MainPage2FragmentArgs(1314)
            findNavController().navigate(R.id.mainPage2Fragment,args.toBundle())
        }
    }
}

MainPage2Fragment.kt

class MainPage2Fragment : Fragment() {
    private val args: MainPage2FragmentArgs by navArgs()
    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                              savedInstanceState: Bundle?): View {
        return inflater.inflate(R.layout.fragment_item2, container, false)
    }

    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)
        content.text = "获取的参数:${args.page2}"
        val args = MainPage3FragmentArgs("哈哈")
        go.setOnClickListener {
            findNavController().navigate(R.id.mainPage3Fragment,args.toBundle())
        }
    }
}

MainPage3Fragment.kt

class MainPage3Fragment : Fragment() {
    private val args: MainPage3FragmentArgs by navArgs()
    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                              savedInstanceState: Bundle?): View {
        return inflater.inflate(R.layout.fragment_item3, container, false)
    }
    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)
        content.text = "获取的参数:${args.page3}"
        go.setOnClickListener {
            findNavController().popBackStack(R.id.mainPage1Fragment,true)

        }
    }
}

注意:

  • 从Activity里面向Fragment传递参数需要使用下面方式

    val args = Bundle()
    val host: NavHostFragment = supportFragmentManager
                .findFragmentById(R.id.nav_host_fragment) as NavHostFragment? ?: return
            navController = host.navController
    navController.navigate(R.id.mainPage1Fragment,args)
    

至此,可以进行简单的代码参数传递了