Navigation导航
概述
Android Jetpack 组件之一,用来实现不同片段(Fragment)之间的交互导航。且遵循谷歌官方导航既定原则。
用途
Navigation 组件旨在用于具有一个主 Activity 和多个 Fragment 目的地的应用。主 Activity 与导航图相关联,且包含一个负责根据需要交换目的地的 NavHostFragment
。
在具有多个 Activity 目的地的应用中,每个 Activity 均拥有其自己的导航图。
优势
- 可视化
- 集中管理
- 自动处理
- 深层链接 Deep Linking
- 动画
- 安全
基础用法
资源文件中新建
res/navigation/navigation.xml
;主
activity
布局中需要有个一fragment
与之(navigation.xml
)绑定;1
2
3
4
5
6
7
8
9
10
11...
//绑定即:后续所有的导航、跳转 都是在这个main_fragment中完成了
//所以要加`app:defaultNavHost="true"`,拦截系统的返回键,fragment内部响应
<fragment
android:id="@+id/main_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:navGraph="@navigation/navigation" />
...
android:name
属性包含NavHost
实现的类名称。app:navGraph
属性将NavHostFragment
与导航图相关联。导航图会在此NavHostFragment
中指定用户可以导航到的所有目的地。(即navigation.xml
)app:defaultNavHost="true"
属性确保您的NavHostFragment
会拦截系统返回按钮。请注意,只能有一个默认NavHost
。如果同一布局(例如,双窗格布局)中有多个主机,请务必仅指定一个默认NavHost
。
新建目标fragment(一个或多个),并在
navigation.xml
中导入,并建立导航(跳转)关系。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<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/HomeFragment">
<fragment
//下一步中方法一对应的fragment的ID
android:id="@+id/HomeFragment"
android:name="com.cy.navigationtest.HomeFragment"
android:label="fragment_home"
tools:layout="@layout/fragment_home" >
//下一步中方法二对应的action的ID
<action
android:id="@+id/next_action"
app:destination="@id/detailFragment" />
</fragment>
<fragment
android:id="@+id/detailFragment"
android:name="com.cy.navigationtest.DetailFragment"
android:label="fragment_detail"
tools:layout="@layout/fragment_detail" />
</navigation>
- 在**主
fragment
**中,在对应场景下进行跳转。有两种跳转方式,代码如下:
方式一:直接跳转到对应fragment,跳转规则可不受
navigation.xml
指使,只要xml中有这个fragment的ID就行。1
2findNavController().navigate(R.id.HomeFragment, null)
//fragment_one:要跳转的fragment在navigation.xml中指定的ID ; null为bundle,可不传。方式二:按
navigation.xml
的规则进行跳转。1
2Navigation.createNavigateOnClickListener(R.id.next_action, null)
//next_action为navigation.xml中指定action的ID; 跳转规则就在这个action中
方式三:使用 Safe Args Gradle 插件
我也还没搞清楚,具体看官网。一款Gradel平台的插件,帮助你生成相关代码。所以要在根项目的gradle中配置如下:
1
2
3
4
5
6
7
8
9buildscript {
repositories {
google()
}
dependencies {
def nav_version = "2.3.1"
classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$nav_version"
}
}然后在app项目的中配置:(二选一)
1
2apply plugin: "androidx.navigation.safeargs" //java
apply plugin: "androidx.navigation.safeargs.kotlin" //kotlin然后,在navigation.xml中目的fragment中加入
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<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/HomeFragment">
<fragment
//下一步中方法一对应的fragment的ID
android:id="@+id/HomeFragment"
android:name="com.cy.navigationtest.HomeFragment"
android:label="fragment_home"
tools:layout="@layout/fragment_home" >
//下一步中方法二对应的action的ID
<action
android:id="@+id/next_action"
app:destination="@id/detailFragment" />
</fragment>
<fragment
android:id="@+id/detailFragment"
android:name="com.cy.navigationtest.DetailFragment"
android:label="fragment_detail"
tools:layout="@layout/fragment_detail" />
<argument
android:name="girl"
app:argType="com.cy.beautygankio.data.Girl" />//记得 Parcelable or Serializable
</navigation>然后编译,gradle会自动为你生成为2个类。
XXXDirections: 此处XXX为起点fragment类名,如:HomeFragmentDirections。
- 该类中有一个方法,方法名是你action的名字,如:nextAction()。
XXXArgs: 此处的XXX为终点(目的)fragment的类名,如DetailFragmentArgs。
跳转的方法如下:
1
2
3
4
5val direction =
XXXXDirections.action方法名(
argument
)
view.findNavController().navigate(direction)接收方法为:
1
2
3
4val args: XXXArgs by navArgs()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
val argument = args.girl
}这种跳转方式官方的说法是可以确保类型安全。
前两种方法就只能用bundle传参了。
1 | arguments?.getSerializable("key") |