Navigation

Navigation 是指允许用户导航、进入和退出应用中不同内容片段的交互。

在Android开发中,navHostnavController是与导航组件(Navigation Component)相关的重要概念。

  1. NavHost(导航宿主)

    • NavHost是一个容器视图,用于承载导航图(Navigation Graph)中定义的目的地(Destination)和动作(Action)。
    • 通常,NavHost是一个Fragment,用于在应用中管理导航和目的地之间的切换。
    • NavHost负责展示导航图中当前目的地的视图,并处理目的地之间的导航。
  2. NavController(导航控制器)

    • NavController是一个控制器对象,用于管理应用中的导航操作。
    • NavController负责处理用户在应用中进行的导航操作,例如从一个目的地导航到另一个目的地。
    • NavControllerNavHost结合使用,NavHost托管NavController实例,并在NavHost中管理导航过程。

因此,NavHostNavController之间的关系是NavHost作为容器视图,承载NavController处理的导航操作。NavHost负责展示当前目的地的视图,而NavController负责处理导航操作,两者共同协作实现应用中的导航功能。

(一)使用步骤

1. 导入依赖
implementation(“androidx.navigation:navigation-fragment-ktx:2.6.0”)
implementation(“androidx.navigation:navigation-ui-ktx:2.6.0”)

2. 创建导航图

res —-> New —-> New Resource Directory —-> navigation
Navigation —-> Navigation Resource File

创建 Fragment 的方式:
在导航图的左上角 ——> New Destination -> Fragment(Blank)
处理好 Fragment 之间的切换关系

右键 ——> Set as Start Destination (该导航图运行起来显示的第一个界面)

1
2
3
4
5
6
7
8
9
10
<fragment
android:id="@+id/welcomeFragment"
android:name="com.example.littlepainter.WelcomeFragment"
android:label="fragment welcome"tools:layout="@layout/fragment welcome">

<!--action对应箭头-->
<action
android:id="@+id/action welcomeFragment to guideFragment2"
app:destination="@id/guideFragment" />
</fragment>

3. 添加 NavHostFragment 控件 ,将 Fragment 显示到 Activity 上
在 activity_main.xml文件中
此时用 navigation 就不能直接使用 fragmentContainerView 了
需要使用 NavHostFragment (本质上还是fragmentContainerView)

在 activity 中添加 NavHostFragment ,并关联对应导航图

1
2
app:defaultNavHost="true" //是否为默认的导航图 默认加载起来显示的导航图
app:navGraph="@navigation/main_nav" //关联的哪个导航图 //显示的内容在navGraph中 关联导航图

4. 导航到目的地(找到 NavController 实现界面切换)

导航到目的地
导航到目的地是使用 NavController 完成的,它是一个在 NavHost 中管理应用导航的对象。每个 NavHost 均有自己的相应 NavController 。
可以使用以下方法之一检索 NavController:

在不同情况下如何找到 NavController :
findNavController()

Fragment —— Fragment.findNavController()
View —— View.findNavController() //知道一个 View 使用 binding.root.findNavController()
Activity —— Activity.findNavController(viewId: Int)

1
findNavController().navigate()

activity 中如果使用的是 FragmentContainerView 实现的 NavHost 就不能使用 Activity.findNavController(viewId: Int)

1
2
val navHostFragment = supportFragmentManager.findFragmentById(R.id.fragmentContainerView) as NavHostFragment
val navController = navHostFragment.navController

(二)action 线

Pop Behavior 管理堆栈信息

(线 界面返回的销毁)

线(action):
Pop Behavior
popUpTo: 把这个界面上面的所有界面出栈
popUpToInclusive: true/false 是否包含当前界面也要弹出

(某一个界面如果只希望它显示一次就不能再返回了就可以使用)

Animations 动画

enterAnim 新的进入
exitAnim 当前消失
popEnterAnim 新的进入后怎么弹出去
popExitAnim 旧的怎么弹回来

添加补间动画

1
2
3
4
5
6
7
<action
android:id="@+id/action welcomeFragment to guideFragment2"
app:destination="@id/guideFragment" //目的地
app:popUpTo="@id/drawFragment" //把这个界面上面的所有界面出栈
app:popUpTolnclusive="true" //是否包含当前界面
app:launchSingleTop = "true" // 栈顶单个对象
/>

(三)实现参数传递

使用 Safe Args 传递类型安全的数据

Navigation 组件具有一个名为 Safe Args 的 Gradle 插件,该插件可以生成简单的 object 和 builder 类,以便以类型安全的方式浏览和访问任何关联的参数。
强烈建议将 Safe Args 用于导航和传递数据,因为它可以确保类型安全

  1. 导入插件
1
2
3
4
5
6
7
8
9
10
//1
plugins{
//替换classPath
id 'androidx.navigation.safeargs' version '2.7.7' apply false
}

//2
plugins {
id 'androidx.navigation.safeargs.kotlin'
}
  1. 在需要参数的 destination 中配置这个界面的参数类型和名称
    谁接受参数就到谁的 Fragment 里面设置

在 navigate 导航图中 ——> Arguments ——> +

Name 参数名
Type 参数类型
Array Nullable
Default Value 默认值

普通的参数

传递
…FragmentDirections

1
2
val action = WelcomeFragmentDirections.actionWelcomeFragmentToHomeFragment(10)
findNavController().navigate(action)

接收
…FragmentArgs by navArgs()

1
2
3
4
//获取传递过来的参数对象
private val args: HomeFragmentArgs by navArgs()

binding.textView.text = args.number.toString()

传递一个类(传递特殊类型参数)

序列化对象是指将一个对象转换为字节流的过程,以便在网络传输或存储到本地文件中。
序列化对象可以方便地在不同组件之间传递数据,提高应用的灵活性和扩展性。

常用的序列化方式包括使用 Serializable 接口或 Parcelable 接口来实现对象的序列化。

要实现序列化接口 Parcelable
需要导入序列化插件:

1
2
3
4
5
//2
plugins {
id 'kotlin-parcelize'
}

1
2
3
4
@Parcelize
data class User constructor(
val name:String,
val age:lnt):Parcelable
Donate
  • Copyright: Copyright is owned by the author. For commercial reprints, please contact the author for authorization. For non-commercial reprints, please indicate the source.

扫一扫,分享到微信

微信分享二维码
  • Copyrights © 2023-2025 Annie
  • Visitors: | Views:

嘿嘿 请我吃小蛋糕吧~

支付宝
微信