Navigation是什么
Navigation翻译过来就是导航。
导航是指支持用户导航、进入和退出应用中不同内容片段的交互。Android Jetpack 的导航组件可帮助您实现导航,无论是简单的按钮点击,还是应用栏和抽屉式导航栏等更为复杂的模式,该组件均可应对。导航组件还通过遵循一套既定原则来确保一致且可预测的用户体验。
导航组件由以下三个关键部分组成:
-
导航图:在一个集中位置包含所有导航相关信息的 XML 资源。这包括应用内所有单个内容区域(称为目标)以及用户可以通过应用获取的可能路径。
-
NavHost:显示导航图中目标的空白容器。导航组件包含一个默认 NavHost 实现 (NavHostFragment),可显示 Fragment 目标。
-
NavController:在 NavHost 中管理应用导航的对象。当用户在整个应用中移动时,NavController 会安排 NavHost 中目标内容的交换。
在应用中导航时,您告诉 NavController,您想沿导航图中的特定路径导航至特定目标,或直接导航至特定目标。NavController 便会在 NavHost 中显示相应目标。
导航组件提供各种其他优势,包括以下内容:
-
处理 Fragment 事务。
-
默认情况下,正确处理往返操作。
-
为动画和转换提供标准化资源。
-
实现和处理深层链接。
-
包括导航界面模式(例如抽屉式导航栏和底部导航),用户只需完成极少的额外工作。
-
Safe Args - 可在目标之间导航和传递数据时提供类型安全的 Gradle 插件。
-
ViewModel 支持 - 您可以将 ViewModel 的范围限定为导航图,以在图表的目标之间共享与界面相关的数据。
-
此外,您还可以使用 Android Studio 的 Navigation Editor 来查看和编辑导航图。
以上内容来自官方文档(我只是一个搬运工\(^o^)/)
简单使用
引入Navigation
在需要使用Navigation的模块的build.gradle中引入
def nav_version = "2.3.0-alpha01"
implementation "androidx.navigation:navigation-fragment:$nav_version"
implementation "androidx.navigation:navigation-ui:$nav_version"
建立导航图
在res目录右键-New-Android Resource File
在弹出的界面中,File name可随意输入,Resource type选择Navigation,点击确定
点击确定后,会在res目录下创建navigation目录,以及刚才定义的导航文件
双击打开刚才创建的导航文件,在Design界面可以看到目前还没有内容,可以点击上方的+号图标添加fragment,也可以自己手动在xml中添加
我们需要为这个文件指定startDestination,即起始的界面
startDestination指定为mainFragment,mainFragment对应的布局为fragment_main
Navigation首先会加载一个默认的Fragment,这个需要在Activity中指定
<?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"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
android:id="@+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:navGraph="@navigation/nav_graph" />
</LinearLayout>
配置defaultNavHost为true,即指定这个fragment为默认的NavHost,每个导航图只能指定一个默认的NavHost。这里的name
配置为androidx.navigation.fragment.NavHostFragment
,navGraph
配置为nav_graph,即指定nav_graph为导航图。这样当Activity启动时,会首先通过activity布局里的fragment去加载导航图中的startDestination配置的fragment。
导航
通过一个Fragment导航到另一个Fragment,可以通过
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_main, container, false);
loginBtn = view.findViewById(R.id.fragment_main_login);
loginBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Bundle bundle = new Bundle();
bundle.putString("name", "zs");
Navigation.findNavController(v).navigate(R.id.action_mainFragment_to_loginFragment, bundle);
}
});
return view;
}
这里通过点击一个按钮进行跳转,通过Navigation.findNavController(v).navigate()
方法导航。这里还可以通过Bundle进行传值。
在目的Fragment,可以通过getArguments()
来获取到传递过来的数据
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
String name = getArguments().getString("name", "null");
Toast.makeText(getContext(), name, Toast.LENGTH_SHORT).show();
View view = inflater.inflate(R.layout.fragment_login, container, false);
backBtn = view.findViewById(R.id.fragment_login_back);
backBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Navigation.findNavController(v).popBackStack();
}
});
return view;
}
在目的Fragment,还可以通过一个按钮返回上一个Fragment:Navigation.findNavController(v).popBackStack()