目录
- 1. Navigation概述
- 2. Navigation组成
- 3. 设置环境
- 4. 使用方法
- 4.1. 创建导航图
- 4.1.1. 具体操作
- 4.2. 向Activity添加NavHost
- 4.2.1. 通过 XML 添加
- 4.2.2. 使用布局编辑器添加
- 4.3. 在导航图中创建目的地
- 4.3.1. 具体操作
- 4.4. 连接目的地
- 4.4.1. 具体操作
- 4.5. 目的地之间的导航
- 4.5.1. 具体操作
- 4.6. Navigation的返回
- 4.6.1. 具体操作
- 4.7. 在目的地间传递数据
- 4.7.1. 定义目的地参数
- 4.7.2. 使用Bundle实现数据传递
- 5. 结果示例
1. Navigation概述
Navigation是指支持用户导航、进入和退出应用中不同内容片段的交互。用于处理 Fragment事务,使fragment之间可以自由切换和跳转,同时还包括导航界面模式(例如抽屉式导航栏和底部导航),可以降低用户工作量
2. Navigation组成
- 导航图:在一个集中位置包含所有导航相关信息的 XML 资源。包含用户可以跳转的所有路径,对Navigation来说就像是地图。
- NavHost:用来显示导航图中目标所要展示的内容。
- NavController:在 NavHost 中管理应用导航的对象。负责NavHost里内容的改变
如果要在应用中导航,则通过NavController,沿导航图中的特定路径导航至特定目标,或直接导航至特定目标。NavController 就可以在NavHost里进行跳转。
3. 设置环境
在Module的build.gradle下添加如下依赖,再进行同步,完成环境设置
dependencies {
// 指定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"
// Feature module Support
implementation "androidx. navigation:navigation-dynamic-features-fragment:$nav_version"
// Testing Navigation
androidTestImplementation "androidx. navigation:navigation-testing:$nav_version"
// Jetpack Compose Integration
implementation "androidx.navigation:navigation-compose:$nav_version"
}
4. 使用方法
4.1. 创建导航图
导航图是一种资源文件,其中包含Navigation所有目的地和操作。会显示应用的所有导航路径。
4.1.1. 具体操作
- 在“Project”窗口中,点击 res 目录,然后依次选择 New > Android Resource File。此时系统会显示 New Resource File 对话框。
- 在 File name 字段中输入Navigation的名称,例如“graph”。
- 从 Resource type 下拉列表中选择 Navigation,然后点击 OK。
这样就完成了空白导航图的创建,这时来到res文档下就会看到navigation文件夹还有你创建的导航图
4.2. 向Activity添加NavHost
分成两种方法:
- 通过 XML 添加
- 使用布局编辑器添加
4.2.1. 通过 XML 添加
在activity中加入如下代码
<!-- 这里navGraph的值要改为自己导航图的名字 -->
<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/graph"
tools:layout_editor_absoluteX="1dp"
tools:layout_editor_absoluteY="1dp" />
4.2.2. 使用布局编辑器添加
- 在项目文件列表中,双击 Activity 的布局 XML 文件,以在 Layout Editor 中将其打开。
- 点击右上角的design,在Palette界面内,选择Containers类别,找到“NavHostFragment”,然后将 NavHostFragment 视图拖动到对应的 Activity 上。
- 接下来,会弹出如下对话框,双击自己要使用的导航图,这里是graph
4.3. 在导航图中创建目的地
目的地相当于是导航图中的一个个地点,展示各种界面内容
4.3.1. 具体操作
- 双击导航图,点击右上角的Design,来到下图的 Navigation Editor 界面,点击图中标红图标,然后点击 Create new destination。
- 在接下来的对话框中,创建 Fragment,Android Studio会按照如下配置创建BlankFragment类和fragment_layout布局(fragment_layout中默认采用FrameLayout的布局,可以改成ConstraintLayout)
回到 Navigation Editor 界面就可以看到导航图中已经有了一个目的地
4.4. 连接目的地
操作会将一个目的地连接到另一个目的地,即一个界面是否可以跳转到另一个界面
为了演示,我在上面的基础上再建了一个BlankFragment2
4.4.1. 具体操作
选中目的地后将该目的地右方的圆圈拖到另一个目的地,松开鼠标后两个目的地以箭头连接,如下图所示
4.5. 目的地之间的导航
为了演示,我在blankFragment里增添了一个按钮用来跳转至blankFragment2
4.5.1. 具体操作
- 在系统生成的BlankFragment类里的onCreateView方法里进行改动
- 通过 Navigation.findNavController(view) 方法得到对应 NavController
- 使用 NavController 里的 navigate(int) 方法进行导航,该方法的参数为两目的地之间连接的id或者要导向的目的地id
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_blank, container, false);
View button = view.findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// action_blankFragment_to_blankFragment22为两目的地之间连接的id或者要导航向的目的地id
Navigation.findNavController(view).navigate(R.id.action_blankFragment_to_blankFragment22);
}
});
// Inflate the layout for this fragment
return view;
}
4.6. Navigation的返回
Navigation支持多个返回堆栈可让用户在各个页面之间自由切换,同时不会在任何页面中丢失所处的位置,不需要导航图中有对应的连接就可以进行返回操作
为了演示,我在blankFragment2里增添一个返回按钮
4.6.1. 具体操作
- 在系统生成的BlankFragment类里的onCreateView方法里进行改动
- 通过 Navigation.findNavController(view) 方法得到对应 NavController
- 使用 NavController 里的 popBackStack() 方法即可完成返回
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_blank2, container, false);
Button button2 = view.findViewById(R.id.button2);
button2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//返回
Navigation.findNavController(view).popBackStack();
}
});
// Inflate the layout for this fragment
return view;
}
4.7. 在目的地间传递数据
Navigation 支持通过定义目的地参数将数据附加到导航操作,实现数据在两个fragment间的传输。
为了演示,我在前面的blankFragment和blankFragment2中分别加上EditText和TextView,用来实现传递数据和接收数据
4.7.1. 定义目的地参数
- 在 Navigation Editor 界面中,点击选择接收参数的目的地,这里是blankFragment2
- 在右侧的 Attributes 面板中,点击 Add (+)。
- 在显示的 Add Argument Link 窗口中,输入参数名称、参数类型、参数是否可为 null,以及默认值(如果需要)。
- 点击 Add。请注意,该参数现在会显示在 Attributes 面板的 Arguments 列表中。
查看code该参数已添加到 XML 中。点击 Text 标签页以切换到 XML 视图,就会发现参数已添加到接收该参数的目的地。
如下图所示,我所设置的参数名称为textString,参数类型为string
<fragment
android:id="@+id/blankFragment2"
android:name="com.example.myapplication.BlankFragment2"
android:label="fragment_blank2"
tools:layout="@layout/fragment_blank2" >
<argument
android:name="textString"
app:argType="string" />
</fragment>
4.7.2. 使用Bundle实现数据传递
- 发送方创建 Bundle 对象,将数据放入入 Bundle 对象后,通过 NavController 中的 navigate() 方法传给发送方
EditText editText = view.findViewById(R.id.editText);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String textString = String.valueOf(editText.getText());
Bundle bundle=new Bundle();
bundle.putString("textString", textString);
Navigation.findNavController(view).navigate(R.id.action_blankFragment_to_blankFragment22,bundle);
}
});
- 接收方通过 getArguments() 方法得到 Bundle 对象并可以使用里面的内容
TextView textView = view.findViewById(R.id.textView1);
textView.setText(getArguments().getString("textString"));
这样就可以实现在blankFragment里输入数据传送到blankFragment2里
5. 结果示例
blankFragment 输入效果
blankFragment2 输出效果
原作者:林冠圳
原文链接:原文链接