In this tutorial, we’ll be discussing the Navigation Architecture that is a part of the JetPack.
JetPack is a set of components and libraries introduced at Google I/O 2018 to build better applications.

在本教程中,我们将讨论作为JetPack一部分的导航架构。
JetPack是Google I / O 2018引入的一组组件和库,用于构建更好的应用程序。

Android Jetpack consists of the following components:

Android Jetpack包含以下组件:

Android JetPack导航架构组件 (Android JetPack Navigation Architecture Component)

The Navigation Architecture component is a part of the new AndroidX package that’s introduced since Android SDK 28.

导航体系结构组件是从Android SDK 28开始引入的新AndroidX程序包的一部分。

This component consists of new guidelines to structure your application, especially navigation between Fragments.

该组件由新准则组成,这些新准则用于构建应用程序,尤其是在片段之间导航。

Google recommends the Single Activity Architecture moving forward when using JetPack.
Navigation Architecture gets ride of the complex FragmentTranscation by providing its own set of classes to navigate between fragments. Let’s first look into the guidelines for Navigation Architecture.

Google建议使用JetPack的单活动架构。
导航体系结构通过提供自己的一组类在片段之间进行导航,从而摆脱了复杂的FragmentTranscation的困扰。 首先让我们研究一下导航体系结构的准则。

导航原理 (Principles of Navigation)

  • The app should have a fixed starting destination.该应用程序应具有固定的启动目标。
  • A stack is used to represent the navigation state of an app.堆栈用于表示应用程序的导航状态。
  • The Navigation Up function never exits your app.向上导航功能永远不会退出您的应用程序。
  • Up and Back should function identical in all the other cases.在其他所有情况下,“上”和“后”功能应相同。
  • Deep linking to a destination or navigating to the same destination should yield the same stack.深度链接到目标或导航到相同的目标应产生相同的堆栈。

入门 (Getting Started)

Create a new Android Studio Project. Add the following classpath inside the root build.gradle file:

创建一个新的Android Studio项目。 在root build.gradle文件中添加以下类路径:

buildscript {...repositories {google()}dependencies {...classpath 'android.arch.navigation:navigation-safe-args-gradle-plugin:1.0.0-alpha04'}
}

Inside the app’s build.gradle add the following:

在应用程序的build.gradle添加以下内容:

implementation 'android.arch.navigation:navigation-fragment:1.0.0-alpha04'
implementation 'android.arch.navigation:navigation-ui:1.0.0-alpha04'

Add the following plugin inside app’s build.gradle:

在应用程序的build.gradle添加以下插件:

apply plugin: 'androidx.navigation.safeargs'

项目结构 (Project Structure)

Our project consists of a single activity and two fragments. Let’s see how we arrived at this.

我们的项目包含一个活动和两个片段。 让我们看看我们是如何得出的。

导航图 (Navigation Graph)

A Navigation Graph is the core layer of the Navigation Architecture. It lays out all the fragments/activities and adds all the connections between them.

导航图是导航体系结构的核心层。 它列出了所有片段/活动并添加了它们之间的所有连接。

Within this graph, we address different parts using a few key terms:

在此图中,我们使用一些关键术语来处理不同的部分:

Navigation Graph XML – This is an XML defined which is created inside the res folder. Right click on the res directory and choose New -> Android resource file. Set the title for the file and choose Navigation from the Resource type dropdown as shown below:

导航图XML –这是在res文件夹中创建的XML定义。 右键单击res目录,然后选择“新建”->“ Android资源文件”。 设置文件标题,然后从“资源类型”下拉列表中选择“导航”,如下所示:

This creates a navigation folder inside the res with the relevant file name.

这将在res内创建具有相关文件名的导航文件夹。

Navigation Host Fragment
Inside the Activity layout, we define a Navigation Host Fragment. In our project, we’ve set the navigation host fragment inside the activity_main.xml layout as shown below:

导航主机片段
在活动布局内,我们定义了一个导航主机片段。 在我们的项目中,我们在activity_main.xml布局中设置了导航主机片段,如下所示:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="https://schemas.android.com/apk/res/android"xmlns:app="https://schemas.android.com/apk/res-auto"xmlns:tools="https://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity"><fragmentandroid:id="@+id/my_nav_host_fragment"android:name="androidx.navigation.fragment.NavHostFragment"android:layout_width="match_parent"android:layout_height="match_parent"app:defaultNavHost="true"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintLeft_toLeftOf="parent"app:layout_constraintRight_toRightOf="parent"app:layout_constraintTop_toTopOf="parent"app:navGraph="@navigation/navigation_graph" /></androidx.constraintlayout.widget.ConstraintLayout>
  • app:navGraph: defines which Navigation Graph will be associated with the Navigation Hostapp:navGraph :定义将与导航主机关联的导航图
  • app:defaultNavHost="true": ensures that the Navigation Host intercepts the system back button when pressed.app:defaultNavHost="true" :确保按下时导航主机拦截系统后退按钮。

Destination – A Destination is any fragment or activity where the user can go.

目标 –目标是用户可以去的任何片段或活动。

We can add destinations inside the Navigation Graph Design file as:

我们可以在“导航图设计”文件中添加以下目标:

  • On the left, we have the Destinations在左侧,我们有目的地
  • In the middle, we have the Navigation Graph在中间,我们有导航图
  • On the right, we have the Attributes editor. Inside the attributes editor, we can add actions, pass arguments在右侧,我们有属性编辑器。 在属性编辑器中,我们可以添加操作,传递参数

Notice the circular icon on the FirstFragment when it is highlighted. These are Actions.

请注意, FirstFragment上的圆形图标突出显示时。 这些是动作。

Actions – These are defined to navigate from one fragment/activity to another. We can define them by dragging or in the XML.

动作 –定义为从一个片段/活动导航到另一个片段/活动。 我们可以通过拖动或在XML中定义它们。

An action is created with an id specified. You can choose the transition animations as well from a dropdown list of built-in ones or create your own and specify it.
The XML code gets auto-generated:

创建具有指定ID的操作。 您也可以从内置动画的下拉列表中选择过渡动画,也可以创建自己的动画并进行指定。
XML代码会自动生成:

<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="https://schemas.android.com/apk/res/android"xmlns:app="https://schemas.android.com/apk/res-auto"xmlns:tools="https://schemas.android.com/tools"android:id="@+id/navigation_graph"app:startDestination="@id/firstFragment"><fragmentandroid:id="@+id/firstFragment"android:name="com.journaldev.androidjetpacknavigation.FirstFragment"android:label="navigation_first_fragment"tools:layout="@layout/navigation_first_fragment" ><actionandroid:id="@+id/action_firstFragment_to_secondFragment"app:destination="@id/secondFragment"app:enterAnim="@anim/nav_default_enter_anim"  /></fragment><fragmentandroid:id="@+id/secondFragment"android:name="com.journaldev.androidjetpacknavigation.SecondFragment"android:label="navigation_second_fragment"tools:layout="@layout/navigation_second_fragment" />
</navigation>

The above code can be written directly without the need of the Design Editor.
We’ve added an animation on the action.

无需设计编辑器即可直接编写以上代码。
我们在动作上添加了动画。

Inside the Navigation Graph XML tag, you must specify the startDestination. The application gets launched there.

在Navigation Graph XML标记内,必须指定startDestination 。 该应用程序在那里启动。

The layouts for the First and Second Fragment are:

第一个和第二个片段的布局为:

navigation_first_fragment.xml

navigation_first_fragment.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"xmlns:tools="https://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:background="@color/colorPrimary"android:gravity="center"android:orientation="vertical"tools:context=".FirstFragment"><TextViewandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_margin="16dp"android:gravity="center"android:textSize="22sp"android:textColor="@android:color/white"android:text="This is First Fragment" /><Buttonandroid:id="@+id/button_frag1"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="Go to next screen" />
</LinearLayout>

navigation_second_fragment.xml

navigation_second_fragment.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="https://schemas.android.com/apk/res/android"xmlns:tools="https://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:background="@color/colorAccent"android:gravity="center"tools:context=".SecondFragment"><TextViewandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_centerInParent="true"android:gravity="center"android:text="This is Second Fragment"android:textColor="@android:color/white"android:textSize="22sp" /><Buttonandroid:id="@+id/button_frag2"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_alignParentBottom="true"android:text="Back" /></RelativeLayout>

Now that the layouts are ready, let’s see how to navigate from one Fragment to the other via the actions.
NavController manages app navigation within the NavHost.

现在已经准备好布局,让我们看看如何通过操作从一个Fragment导航到另一个Fragment。
NavController管理中的应用程序导航NavHost

The code for the FirstFragment.java class is:

FirstFragment.java类的代码为:

package com.journaldev.androidjetpacknavigation;import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.navigation.NavController;
import androidx.navigation.NavDirections;
import androidx.navigation.Navigation;public class FirstFragment extends Fragment {@Nullable@Overridepublic View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {return inflater.inflate(R.layout.navigation_first_fragment, container, false);}@Overridepublic void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {super.onViewCreated(view, savedInstanceState);View.OnClickListener s = Navigation.createNavigateOnClickListener(R.id.action_firstFragment_to_secondFragment);Button button = view.findViewById(R.id.button_frag1);button.setOnClickListener(s);}}

We pass the action id inside the createNavigateOnClickListener method. There are a few alternative ways to navigate as well:

我们在createNavigateOnClickListener方法内部传递操作ID。 还有几种其他导航方式:

Alternative Way 1
We can navigate using the following code as well:

替代方法1
我们也可以使用以下代码进行导航:

final NavController navController = Navigation.findNavController(getActivity(), R.id.my_nav_host_fragment);button.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {navController.navigate(R.id.action_firstFragment_to_secondFragment);}});

Alternative Way 2

替代方法2

final NavDirections navDirections = FirstFragmentDirections.actionFirstFragmentToSecondFragment();
final NavController navController = Navigation.findNavController(getActivity(), R.id.my_nav_host_fragment);button.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {navController.navigate(navDirections);}});

传递参数 (Passing Arguments)

The navigation architecture comes with a built-in way to pass type-safe arguments from one Fragment to the other.

导航体系结构内置了一种将类型安全参数从一个Fragment传递到另一个Fragment的内置方法。

You can define them in the Navigation Graph design editor as:

您可以在“导航图”设计编辑器中将它们定义为:

and/or in XML:

和/或XML:

<fragmentandroid:id="@+id/firstFragment"android:name="com.journaldev.androidjetpacknavigation.FirstFragment"android:label="navigation_first_fragment"tools:layout="@layout/navigation_first_fragment" ><argumentandroid:name="test_string"android:defaultValue="hello world"app:argType="string" /></fragment>

app:argType should be used in place of app:type. app:type is deprecated.

app:argType应该代替app:type 。 app:type已弃用。

Now when we navigate these args get automatically passed.
We can also pass more arguments programmatically.

现在,当我们导航时,这些参数会自动传递。
我们还可以通过编程方式传递更多参数。

Our onViewCreated method of the FirstFragment now becomes:

现在,我们的FirstFragment的onViewCreated方法变为:

@Overridepublic void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {super.onViewCreated(view, savedInstanceState);final Bundle bundle = new Bundle();bundle.putBoolean("test_boolean", true);final NavController navController = Navigation.findNavController(getActivity(), R.id.my_nav_host_fragment);Button button = view.findViewById(R.id.button_frag1);button.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {navController.navigate(R.id.action_firstFragment_to_secondFragment, bundle);}});}

The code for the SecondFragment.java class is:

SecondFragment.java类的代码是:

package com.journaldev.androidjetpacknavigation;import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.Toast;import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.navigation.NavController;
import androidx.navigation.NavDestination;
import androidx.navigation.Navigation;public class SecondFragment extends Fragment {@Nullable@Overridepublic View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {return inflater.inflate(R.layout.navigation_second_fragment, container, false);}@Overridepublic void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {super.onViewCreated(view, savedInstanceState);Toast.makeText(getActivity().getApplicationContext(), "Bundle args " + getArguments().getBoolean("test_boolean"), Toast.LENGTH_SHORT).show();Toast.makeText(getActivity().getApplicationContext(), "Bundle args " + FirstFragmentArgs.fromBundle(getArguments()).getTestString(), Toast.LENGTH_SHORT).show();Button button = view.findViewById(R.id.button_frag2);button.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {final NavController navController = Navigation.findNavController(getActivity(), R.id.my_nav_host_fragment);navController.navigateUp();navController.addOnNavigatedListener(new NavController.OnNavigatedListener() {@Overridepublic void onNavigated(@NonNull NavController controller, @NonNull NavDestination destination) {Log.d("TAG", destination.getLabel() + " ");}});}});}}

The arguments passed in the Navigation Graph have auto-generated getters when you re-build the project.

重建项目时,“导航图”中传递的参数具有自动生成的吸气剂。

FirstFragmentArgs.fromBundle(getArguments()).getTestString() is used to retrieve the argument passed from the FirstFragment.
navigateUp() is used to return to the previous fragment.
addOnNavigatedListener is called when the navigation is completed.

FirstFragmentArgs.fromBundle(getArguments()).getTestString()用于检索从FirstFragment传递的参数。
navigateUp()用于返回上一个片段。
导航完成后,将调用addOnNavigatedListener

The output of the application in action is:

实际应用程序的输出为:

This brings an end to this tutorial. You can download the project from the link below:

本教程到此结束。 您可以从下面的链接下载项目:

AndroidJetpackNavigationAndroidJetpackNavigation
AndroidJetpackNavigationAndroidJetpackNavigation

翻译自: https://www.journaldev.com/22299/android-jetpack-navigation-architecture

Android JetPack –导航架构相关推荐

  1. Android Jetpack导航组件——Navigation的使用

    概述 Navigation是采用一个Activity和多个Fragment形式设计的Ui架构模式,但是众所周知,Fragment的管理一直是个麻烦事,需要通过FragmentManager和Fragm ...

  2. Android Jetpack 库架构组件 Room+Paging 基础使用

    上篇文章 Android Jetpack 库架构组件 ViewModel+LiveData 基础使用 的示例2中,使用 ViewModel+ LiveData 的方式实现了数据库数据查询并分页显示的效 ...

  3. 手动依赖注入的Android Jetpack导航aka也不要用火箭筒射击

    I was reading again my article about Jetpack Navigation, in particular the part regarding the parame ...

  4. Android Jetpack架构组件(一)带你了解Android Jetpack

    本文首发于微信公众号「后厂村码农」 前言 Android已经发展了11年,可以说是比较成熟的技术了,一开始时框架很少,也没有什么规范,所有的代码都是要自己写,比如网络请求,数据库请求,数据解析等等.后 ...

  5. Jetpack架构组件 (一)-- Android Jetpack 简介

    前言 Android 已经发展十多年了,可以说是比较成熟的技术了,一开始时框架很少,也没有什么规范,所有的代码都是要自己写,比如网络请求,数据库操作,数据解析等等.后来出现了一些框架来帮助开发者快速进 ...

  6. Android Jetpack架构组件之 Room(使用、源码篇)

    2019独角兽企业重金招聘Python工程师标准>>> 1.前言 最近简单看了下google推出的框架Jetpack,感觉此框架的内容可以对平时的开发有很大的帮助,也可以解决很多开发 ...

  7. android 使用4大组件的源码,Android Jetpack架构组件之 Paging(使用、源码篇)

    1.前言 最近简单看了下google推出的框架Jetpack,感觉此框架的内容可以对平时的开发有很大的帮助,也可以解决很多开发中的问题,对代码的逻辑和UI界面实现深层解耦,打造数据驱动型UI界面. A ...

  8. Android JetPack架构篇,一个实战项目带你学懂JetPack

    第五届世界互联网大会昨日开幕,来自76个国家的1500余位嘉宾出席大会.腾讯公司董事会主席兼首席执行官马化腾在大会开幕式演讲中表示,全球产业都在进行数字化,在此期间机遇挑战并存,产业互联网机会巨大. ...

  9. Android Jetpack架构组件之Navigation

    Navigation 导航是指支持用户导航.进入和退出应用中不同内容片段的交互.Android Jetpack 的导航组件可帮助您实现导航,无论是简单的按钮点击,还是应用栏和抽屉式导航栏等更为复杂的模 ...

最新文章

  1. 【Tools】cmake 常用变量和常用环境变量查表手册---整理
  2. linux开机自动启动开机日志,设置linux开机自动运行脚本
  3. jq设置保留两位小数_如何实现python中format函数保留指定位数的小数?
  4. Linux iptables 防火墙常用规则
  5. ZOJ 3810 A Volcanic Island (2014年牡丹江赛区网络赛B题)
  6. 讯飞庭审语音识别系统亮相最高人民法院工作报告
  7. iOS-Core-Animation-Advanced-Techniques(二)
  8. 创建font_年底干货来了!图案创建、字体、图库、UI套件常见工具大合集!
  9. Eviews(8)进行线性回归(ols一元)与格兰杰(Granger)因果关系检验操作步骤
  10. chrome主页篡改修复
  11. 【HTMLCSS】CSS当中设置背景图片不显示的问题
  12. Android计步器算法实现
  13. 广东工业大学第12届ACM程序设计大赛 Problem H: tmk买礼物
  14. apmserv5.2.6 mysql启动失败_APMServ5.2.6win10系统Apache、MySQL5.1启动失败解决办法
  15. 【智能产品方案】智能跳绳方案开发
  16. js创建二维数组小坑
  17. co-training方法
  18. 参加科学教师与计算机培训总结报告,教师计算机培训心得总结
  19. 2020年4月TIOBE语言排行榜-你知道少儿编程语言Scratch吗
  20. 梦想世界服务器维护,《梦想世界》2012年8月23日服务器维护公告

热门文章

  1. PHP读写指定URL参数的方法
  2. UVALive 4212 Candy
  3. inner/left/right inner
  4. [转载] python-numpy如何初始化数组值全为nan
  5. [转载] pandas入门
  6. FastAdmin composer json 版本说明
  7. 2017.8.11 think list
  8. html中script标签的使用方法
  9. 【被C折腾系列】用C调DIOCP编码客户端通信
  10. nopcommerce笔记3 还可以控制什么