Android Navigation使用

Jetpack Navigation

概述

  • Navigation是一个可简化Android导航的库和插件

  • Navigation通过管理Fragment的切换,可以通过可视化的方式,看见App的交互流程

  • 可以配置Fragment的过渡和切换动画

  • SafeArgs插件,数据传递时提供了类型安全

官方文档

官方Demo

添加依赖

模块层的build.gradle

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

如果需要使用SafeArgs插件,还需要以下配置

项目的build.gradle

buildscript {
    dependencies {
        //SafeArgs插件
        classpath "androidx.navigation:navigation-safe-args-gradle-plugin:2.0.0"

    }
}

模块层的build.gradle

apply plugin: 'androidx.navigation.safeargs'

Navigation说明

Navigation组成说明
Navigation Graph导航图,可视化显示Fragment之间关系
NavHostFragmentFragment容器
NavController导航的控制者

导航图

navigation属性说明
app:startDestination导航图的开始

Fragment容器

属性说明
android:name必须是androidx.navigation.fragment.NavHostFragment
app:navGraph指定导航图
app:defaultNavHost=“true”与系统返回按钮关联

导航控制者

api说明
findNavController获取导航者
navigate跳转指定目标

基本使用

模拟登陆注册

在这里插入图片描述

定义导航图

在res目录下心间navigation目录,在该目录下新建welcome_navigation.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/login_navigation"
    app:startDestination="@id/welcome">

    <fragment
        android:id="@+id/welcome"
        android:name="com.example.navigationdemo.login.WelcomeFragment"
        android:label="欢迎"
        tools:layout="@layout/fragment_welcome">
        <action
            android:id="@+id/action_to_login"
            app:destination="@id/login" />
        <action
            android:id="@+id/action_to_register"
            app:destination="@id/register"
            app:enterAnim="@anim/common_slide_in_right"
            app:exitAnim="@anim/common_slide_out_left"
            app:popEnterAnim="@anim/common_slide_in_left"
            app:popExitAnim="@anim/common_slide_out_right" />
    </fragment>

    <fragment
        android:id="@+id/login"
        android:name="com.example.navigationdemo.login.LoginFragment"
        android:label="登陆"
        tools:layout="@layout/fragment_login" />

    <fragment
        android:id="@+id/register"
        android:name="com.example.navigationdemo.login.RegisterFragment"
        android:label="注册"
        tools:layout="@layout/fragment_register">
        <!--SafeArgs-->
        <argument
            android:name="data"
            android:defaultValue="default"
            app:argType="string" />
    </fragment>

</navigation>
创建NavHostFragment

新建WelcomeActivity,在其xml布局里写入:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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=".login.WelcomeActivity">

    <fragment
        android:id="@+id/my_welcome_fragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:defaultNavHost="true"
        app:navGraph="@navigation/welcome_navigation" />

</FrameLayout>
定义导航逻辑
class WelcomeFragment : Fragment() {

    private lateinit var btnToLogin: Button
    private lateinit var btnToRegister: Button

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

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        btnToLogin = view.findViewById<Button>(R.id.btn_to_login)
        btnToRegister = view.findViewById<Button>(R.id.btn_to_register)

        //利用id导航
        btnToLogin.setOnClickListener {
            val navOptions = navOptions {
                anim {
                    enter = R.anim.common_slide_in_right
                    exit = R.anim.common_slide_out_left
                    popEnter = R.anim.common_slide_in_left
                    popExit = R.anim.common_slide_out_right
                }
            }
            val bundle = Bundle()
            bundle.putString("data", "1234567")
            findNavController().navigate(R.id.login, bundle, navOptions)
        }

        //使用SafeArags导航
        btnToRegister.setOnClickListener {
            val action = WelcomeFragmentDirections
            .actionToRegister()
            .setData("ABCDEFG")
            findNavController().navigate(action)
        }
    }
}
定义导航目标

LoginFragment

class LoginFragment : Fragment() {
    private lateinit var content: TextView

    private var param: String? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        arguments?.let {
            param = it.getString("data")
        }
    }

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

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        content = view.findViewById<TextView>(R.id.content)
        content.setText("接收数据:$param")
    }
}

RegisterFragment

class RegisterFragment : Fragment() {
    private lateinit var content: TextView

    private var param: String? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        arguments?.let {
            param = it.getString("data")
        }
    }

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

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        val content = view.findViewById<TextView>(R.id.content)
        content.text = "接收数据:$param"
    }
}

模拟底部切换Fragment

在这里插入图片描述

定义导航图
<?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/tab_navigation"
    app:startDestination="@id/first_fragment">

    <fragment
        android:id="@+id/first_fragment"
        android:name="com.example.navigationdemo.tab.FirstFragment"
        android:label="第一页"
        tools:layout="@layout/fragment_first" />

    <fragment
        android:id="@+id/second_fragment"
        android:name="com.example.navigationdemo.tab.SecondFragment"
        android:label="第二页"
        tools:layout="@layout/fragment_second" />

    <fragment
        android:id="@+id/third_fragment"
        android:name="com.example.navigationdemo.tab.ThirdFragment"
        android:label="第三页"
        tools:layout="@layout/fragment_third" />

</navigation>
创建NavHostFragment和定义导航逻辑

新建TabActivity在xml布局写入:

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

    <fragment
        android:id="@+id/my_tab_fragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="match_parent"
        android:layout_height="0px"
        android:layout_weight="1"
        app:defaultNavHost="true"
        app:navGraph="@navigation/tab_navigation" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:background="@color/white"
        android:orientation="horizontal">

        <TextView
            android:id="@+id/switch_first"
            android:layout_width="0px"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:background="#f00"
            android:gravity="center"
            android:text="第一页" />

        <TextView
            android:id="@+id/switch_second"
            android:layout_width="0px"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:background="#0f0"
            android:gravity="center"
            android:text="第二页" />

        <TextView
            android:id="@+id/switch_third"
            android:layout_width="0px"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:background="#00f"
            android:gravity="center"
            android:text="第三页" />

    </LinearLayout>

</LinearLayout>
class TabActivity : AppCompatActivity() {
    private lateinit var switchFirst: TextView
    private lateinit var switchSecond: TextView
    private lateinit var switchThird: TextView

    val navOptions = navOptions {
        anim {
            enter = R.anim.common_fade_in
            exit = R.anim.common_fade_out
            popEnter = R.anim.common_fade_in
            popExit = R.anim.common_fade_out
        }
    }
    val bundle = Bundle()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_tab)
        switchFirst = findViewById<TextView>(R.id.switch_first)
        switchSecond = findViewById<TextView>(R.id.switch_second)
        switchThird = findViewById<TextView>(R.id.switch_third)

//        val navHostFragment =
//            supportFragmentManager.findFragmentById(R.id.my_tab_fragment) as NavHostFragment
//        val navController = navHostFragment.navController

        val navController = findNavController(R.id.my_tab_fragment)

        switchFirst.setOnClickListener {
            navController.navigate(R.id.first_fragment, bundle, navOptions)
        }
        switchSecond.setOnClickListener {
            navController.navigate(R.id.second_fragment, bundle, navOptions)
        }
        switchThird.setOnClickListener {
            navController.navigate(R.id.third_fragment, bundle, navOptions)
        }
    }
}

代码下载

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值