目录
Navigation 翻译成中文就是导航的意思,是Jetpack的一个组件,其目的主要就是来管理页面的切换和导航。
优势
- 可视化的页面导航图
- 通过destinationhe action完成页面间导航
- 方便添加页面切换动画
- 页面间类型安全的参数传递
- 通过NavigationUI类,对菜单、底部导航抽屉菜单导航进行统一管理
- 支持深层链接DeepLink
组成
- Navigation Graph (导航图) 是一种新型xml资源,包含应用程序所有页面及导航路径
- NavHostFragment 是特殊的Fragment,可以理解成其他Fragment的“容器”。
- NavController 是Java/Kotlin对象,完成具体页面的切换工作。
三者关系
当你想要切换Fragment时,使用NavController对象,告诉它你想要去Navigation Graph中的哪个Fragmet,NavController会将你想取的Fragment展示NavHostFragment中
使用
1. 添加依赖
implementation 'androidx.navigation:navigation-fragment:2.4.1'
implementation 'androidx.navigation:navigation-ui:2.4.1'
2. 在res目录下创建导航图(xml文件)
依次选中res文件夹–>New–>Android Resource File,新建一个Navigation Graph;
将File name 设置为“nav_graph”,Resource type(选择)设置为 “Navigation”
点击Ok就可以了。
生成的nav_graph.xml文件与普通的布局文件类似,
3 NavHostFragment添加
NavHostFragment是一个特殊的Fragment,我们一般将其添加到Activity、Fragment,此时添加到Activity种,作为其他Fragment的容器
说明这是一个特殊的Fragment
android:name="androidx.navigation.fragment.NavHostFragment"
设置为true,则该Fragment会自动处理系统返回键。
app:defaultNavHost="true"
用于设置Fragment对应的导航图
app:navGraph="@navigation/nav_graph"
4. 创建destination
双击“Click to add a destintion”
destination 是“目的地”,就是要去的页面,可以是Fragment或Activity,常见的是Fragment。
运行效果
5 Fragment 页面切换
用同样的方式创建SecondFragment,然后,单击mainFragment,用鼠标选中右侧的圆圈,并拖拽之右边的SecondFragment,松开鼠标。
会出现一个从mainFragment指向SecondFragment的箭头
该属性表示指定起始destaination为mainFragment.
app:startDestination="@id/mainFragment"
看到多了一个action标签
<action
android:id="@+id/action_mainFragment_to_secondFragment2"
app:destination="@id/secondFragment" />
app:destination=“@id/secondFragment” 属性表示它的目的地是SecondFragment
fragment_main.xml文件
6添加页面切换效果
在res文件下,创建anim文件,
动画
slide_in_from_left
<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="2000"
android:fromXDelta="-100%"
android:toXDelta="0" />
slide_in_from_right
<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="2000"
android:fromXDelta="100%"
android:toXDelta="0" />
slide_out_from_left
<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="2000"
android:fromXDelta="0"
android:toXDelta="-100%" />
slide_out_from_right
<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="2000"
android:fromXDelta="0"
android:toXDelta="100%" />
这里就不查看效果了。
7 使用safe args传递参数
Fragment 的切换通常是伴随着参数的传递,为了配合使用Navigation组件在切换Fragment时传递参数,As提供了safe args插件。
Frament间最常见的传递参数和接受参数的方法
- 传递参数
Bundle bundle = new Bundle();
bundle.putString("name", "Alan");
bundle.putString("age", "30");
Navigation.findNavController(v).navigate(R.id.action_mainFragment_to_secondFragment2, bundle);
- 接收参数
Bundle arguments = getArguments();
if (arguments != null) {
String name = arguments.getString("name");
int age = arguments.getInt("age");
}
safe args呢?
- 添加safe args 插件,在根目录下build.gradle中添加
classpath "androidx.navigation:navigation-safe-args-gradle-plugin:2.3.5"
- 在 app的build.gradle中添加添加对safe args的依赖
apply plugin 'androidx.navigation.safeargs.kotlin'
3.在导航图中添加标签,可以在Text中编写,也可以通过Design进行添加。
<argument
android:name="user_name"
android:defaultValue="Alan"
app:argType="string" />
<argument
android:name="age"
android:defaultValue="18"
app:argType="integer" />
添加完会在app/generatedJava目录下看到 safe args 插件生成的代码文件了。
需要在Fragment中用插件生成的代码,在Fragment直接传递参数。
传递参数
Bundle bundle new MainFragmentArgs().Builder()
.setUerName("Alan")
.setAge(18)
.build()
.toBundle();
Navigation.findNavController(v)
.navigate(R.id.action_mainFragment_to_secondFragment2,bundle);
接受参数
Bundle bundle1 = getArguments();
if (bundle1 != null){
String userName = MainFragmentArgs().fromBundle(getArguments().getUerName());
int ages = MainFragmentArgs().fromBundle(getArguments().getAge());
}
safe args 好处在于安全的参数类型。