10.Navigation
Navigation概述
1 2 Navigation是指支持用户导航、进入和退出应用中不同内容片段的交互。用于处理Fragment事务,使fragment之间可以自由切换和跳转, 同时还包括导航界面模式(例如抽屉式导航栏和底部导航),可以降低用户工作量;
Navigation组成 (核心三件套)
1 2 3 4 5 1.导航图:在一个集中位置包含所有导航相关信息的 XML 资源。包含用户可以跳转的所有路径,对Navigation来说就像是地图。 2.NavHost:用来显示导航图中目标所要展示的内容。 3.NavController:在 NavHost 中管理应用导航的对象。负责NavHost里内容的改变 如果要在应用中导航,则通过NavController,沿导航图中的特定路径导航至特定目标,或直接导航至特定目标。NavController 就可以 在NavHost里进行跳转。
1 2 3 4 5 6 7 8 9 10 11 // 指定Navigation的版本 def nav_version = "2.5.3" // Java language implementation implementation "androidx.navigation:navigation-fragment:$nav_version" implementation "androidx.navigation:navigation-ui:$nav_version" // Kotlin implementation "androidx.navigation:navigation-fragment-ktx:$nav_version" implementation "androidx.navigation:navigation-ui-ktx:$nav_version"
导航图使用方法
1.创建导航图
导航图是一种资源文件,其中包含Navigation所有目的地和操作。会显示应用的所有导航路径。
1.1. 具体操作
1 2 3 4 1.在“Project”窗口中,点击 res 目录,然后依次选择 New > Android Resource File。此时系统会显示 New Resource File 对话框。 2.在 File name 字段中输入Navigation的名称,例如“graph”。 3.从 Resource type 下拉列表中选择 Navigation,然后点击 OK。 这样就完成了空白导航图的创建,这时来到res文档下就会看到navigation文件夹还有你创建的导航图
2.向Activity添加NavHost
分成两种方法:
1 2 1. 通过 XML 添加 2. 使用布局编辑器添加(暂不介绍)
2.1. 通过 XML 添加
在activity中加入如下代码
1 2 3 4 5 6 7 8 9 10 <!-- 这里navGraph的值要改为自己导航图的名字 --> <!-- app.defaultNavHost="true"表示回退栈由fragment管理 --> <androidx.fragment.app.FragmentContainerView android:id="@+id/fragmentContainerView" android:name="androidx.navigation.fragment.NavHostFragment" android:layout_width="409dp" android:layout_height="729dp" app:defaultNavHost="true" app:navGraph="@navigation/navigation_map" />
3.在导航图中创建目的地
目的地相当于是导航图中的一个个地点,展示各种界面内容
3.1. 具体操作
1.双击导航图,点击右上角的Design,来到下图的 Navigation Editor 界面,点击图中标红图标,然后点击 Create new destination。
2.在接下来的对话框中,创建 Fragment,Android Studio会按照如下配置创建BlankFragment类和fragment_layout布局(fragment_layout中默认采用FrameLayout的布局,可以改成ConstraintLayout)
回到 Navigation Editor 界面就可以看到导航图中已经有了一个目的地
3.连接目的地
操作会将一个目的地连接到另一个目的地,即一个界面是否可以跳转到另一个界面
为了演示,我在上面的基础上再建了一个BFragment
3.1. 具体操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 1.在系统生成的AFragment类里的onCreateView方法里进行改动 2.通过 Navigation.findNavController(view) 方法得到对应 NavController 3.使用 NavController 里的 navigate(int) 方法进行导航,该方法的参数为两目的地之间连接的id或者要导向的目的地id public class AFragment extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View inflate = inflater.inflate(R.layout.fragment_a, container, false); inflate.findViewById(R.id.tv_text).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // action_AFragment_to_BFragment为两目的地之间连接的id或者要导航向的目的地id,这个id在navigation_map //的右上角自动生成的 Navigation.findNavController(v).navigate(R.id.action_AFragment_to_BFragment); } }); return inflate; } }
3.2Navigation的返回
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 Navigation支持多个返回堆栈可让用户在各个页面之间自由切换,同时不会在任何页面中丢失所处的位置,不需要导航图中有对应的连接就可 以进行返回操作 具体操作: 1.在系统生成的BlankFragment类里的onCreateView方法里进行改动 2.通过 Navigation.findNavController(view) 方法得到对应 NavController 3.使用 NavController 里的 popBackStack() 方法即可完成返回 public class BFragment extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View inflate = inflater.inflate(R.layout.fragment_b, container, false); inflate.findViewById(R.id.tvback).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //返回 Navigation.findNavController(v).popBackStack(); } }); return inflate; } }
4.在目的地间传递数据(不研究导航地图的传参了,麻烦无用)
1 2 3 Bundle bundle=new Bundle(); bundle.putString("name", "tyl"); Navigation.findNavController(v).navigate(R.id.action_AFragment_to_BFragment,bundle);
接收方通过 getArguments() 方法得到 Bundle 对象并可以使用里面的内容
1 String name = getArguments().getString("name");
//BottomNavigationView看了下可扩展性差,不适合正式项目使用,直接不采用这个框架