之前一直使用FragmentManager进行Fragment管理,最近发现Android官方早就出了更好用的组件,那么我就在此记录一下,既能方便他人上手,也能巩固自己的记忆。

此处主要实现在Acitivty下加载Fragment以及Activity对Fragment进行传值,Fragment之间的切换以及传值。

因为时间有限,文章的内容没有细写,主要还是为了备忘,后期有时间可以考虑认真写一期,包括多种加载方式等等,还请看官见谅。

一、添加Gradle依赖

在App目录下添加navigation依赖

dependencies {
    implementation "androidx.navigation:navigation-fragment-ktx:2.4.2"
    implementation "androidx.navigation:navigation-ui-ktx:2.4.2"
}

二、相应文件代码

1.FragmentIndexActivity下的代码

Kotlin代码:

class FragmentIndexActivity : AppCompatActivity(R.layout.activity_fragment_index) {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // 传递的bundle
        val testBundle = Bundle()
        testBundle.putString("text", "传递值:点击跳转页面")
        // 获取NavHostFragment实例
        val navHost = supportFragmentManager.findFragmentById(
            R.id.container_view
        ) as NavHostFragment
        // 通过NavHostFragment获取NavController实例
        val controller = navHost.navController
        // 通过NavController获取NavGraph实例
        val graph = controller.graph
        // 新建一个NavFragment对应的传递参数Argument
        val builder = NavArgumentBuilder()
        builder.defaultValue = testBundle
        val argument = builder.build()
        // 将参数Argument添加到NavGraph中以便Fragment使用
        graph.addArgument("arg", argument)
    }
}

XML布局文件:

<?xml version="1.0" encoding="utf-8"?>
<!--    此处的nav_graph文件请参考后面的文档-->
<androidx.fragment.app.FragmentContainerView 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/container_view"
    android:name="androidx.navigation.fragment.NavHostFragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:defaultNavHost="false"
    app:navGraph="@navigation/nav_graph"
    tools:context=".fragment.FragmentIndexActivity">

</androidx.fragment.app.FragmentContainerView>

2. 两个Fragment的代码

1. FirstFragment下的代码

Kotlin代码:

class FirstFragment : Fragment() {

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

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        // 获取此前在Activity中设置的NavGraph中的参数
        val map = findNavController().graph.arguments
        val argument = map["arg"]
        val bundle = argument?.defaultValue as Bundle
        // 获取Bundle中的值
        val text = bundle.getString("text", "")
        // 设置Button显示的文字
        mBtnSecond.text = text
        val secondBundle = Bundle()
        secondBundle.putString("second", "传递到下一个Fragment的值")
        // 跳转至第二个Fragment页面,并且传递参数
        mBtnSecond.setOnClickListener {
            findNavController().navigate(R.id.action_firstFragment_to_secondFragment, secondBundle)
        }

    }

}

XML布局代码:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
    android:gravity="center"
    tools:context=".fragment.FirstFragment">

    <Button
        android:id="@+id/mBtnSecond"
        android:layout_width="200dp"
        android:layout_height="60dp"
        android:text="点击跳转SecondFragment" />

</LinearLayout>

2. SecondFragment下的代码

Kotlin代码:

class SecondFragment : Fragment() {

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_second, container, false)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        // 此处Fragment依然可以获取在Activity下设置的NavGraph中的值
        val map = findNavController().graph.arguments
        val activityArgument = map["arg"]
        val bundle = activityArgument?.defaultValue as Bundle
        val text = bundle.getString("text", "")
        println("这是从上层Activity中传递过来的值:${text}")
        // 此处获取从FirstFragment中传递的值
        val secondText = arguments?.getString("second", "")
        mBtnFirst.text = secondText
        mBtnFirst.setOnClickListener {
            // 点击返回上一层Fragment
            findNavController().navigate(R.id.action_secondFragment_pop)
        }
    }

}

XML布局代码:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
    android:gravity="center_horizontal"
    android:orientation="vertical"
    tools:context=".fragment.SecondFragment">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:text="这是SecondFragment"
        android:textColor="@color/black"
        android:textSize="15sp" />

    <Button
        android:id="@+id/mBtnFirst"
        android:layout_width="150dp"
        android:layout_height="60dp"
        android:text="点击返回上一级" />
</LinearLayout>

三. 文件nav_graph.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/nav_graph"
    app:startDestination="@id/firstFragment">

    <fragment
        android:id="@+id/firstFragment"
        android:name="cn.com.blina.study_test_20220411.fragment.FirstFragment"
        android:label="fragment_first"
        tools:layout="@layout/fragment_first">
        <action
            android:id="@+id/action_firstFragment_to_secondFragment"
            app:destination="@id/secondFragment"
            app:enterAnim="@anim/nav_default_enter_anim"
            app:exitAnim="@anim/nav_default_exit_anim"
            app:popEnterAnim="@anim/nav_default_pop_enter_anim"
            app:popExitAnim="@anim/nav_default_pop_exit_anim" />
    </fragment>

    <fragment
        android:id="@+id/secondFragment"
        android:name="cn.com.blina.study_test_20220411.fragment.SecondFragment"
        android:label="fragment_second"
        tools:layout="@layout/fragment_second">
        <action
            android:id="@+id/action_secondFragment_pop"
            app:popUpTo="@id/secondFragment"
            app:popUpToInclusive="true" />
    </fragment>
</navigation>

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐