Skip to content

Files

Latest commit

91e702a · Dec 25, 2021

History

History
596 lines (346 loc) · 41.4 KB

File metadata and controls

596 lines (346 loc) · 41.4 KB

三、探索 AndroidStudio 和项目结构

在本章中,我们将创建并运行另外两个安卓项目。这些练习的目的是更深入地探索 Android Studio 和 Android 项目的结构。

当我们构建准备部署的应用时,代码和资源文件需要打包到一个安卓包 ( APK )文件中——恰到好处。因此,所有布局文件(以及我们将很快发现的其他资源)都需要有正确的结构。

幸运的是,当我们从模板创建项目时,AndroidStudio 会为我们处理这个问题。但是,我们仍然需要知道如何查找和修改这些文件,如何添加我们自己的(有时是删除的)Android Studio 创建的文件,以及资源文件是如何相互链接的,有时是相互链接的,有时是与 Java 代码链接的(自动生成的和我们自己的)。

除了了解我们项目的组成之外,确保我们从模拟器中获得最大收益也是有益的。

注意

当你想确保你的应用可以在你没有的硬件上运行时,仿真器特别有用。此外,学习一些最新的功能(正如我们将在本书中介绍的)通常需要最新的手机,模拟器是一种经济高效的方式,可以在不购买最新手机的情况下跟随所有迷你应用。

在本章中,我们将研究以下主题:

  • 探索空活动项目模板的文件和文件夹结构
  • 探索基本活动项目模板的文件和文件夹结构
  • 看到空活动基础活动模板的区别了吗
  • 探索安卓模拟器

本章将为我们在下一章构建和部署多个不同的用户界面 ( UI )设计留下一个很好的位置。

技术要求

你可以在https://GitHub . com/PacktPublishing/Android-初学者编程-第三版/tree/main/章节%2003 找到本章中出现的代码。

项目探索者和项目解剖

当我们创建一个新的 Android 项目时,我们最常使用的是项目模板,就像我们在 第 1 章开始 Android 和 Java 一样。我们使用的模板决定了 AndroidStudio 将生成的文件的确切选择和内容。虽然所有项目都有值得注意的相似之处,但看到差异也有帮助。让我们构建两个模板项目,检查文件、它们的内容以及它们是如何通过代码(可扩展标记语言 ( XML )和 Java 链接在一起的。我们首先创建一个空活动*项目。*

*# 探索空活动项目模板的文件和文件夹结构

带有自动生成用户界面的最简单的项目类型是空活动项目模板。用户界面几乎是空的,但它已经准备好添加到那里了。当我们创建一个甚至有空用户界面的项目时,AndroidStudio 也会自动生成 Java 代码来显示用户界面。因此,当我们将其添加到空 UI 中时,它就可以显示了。

让我们创建一个空活动项目。这个过程和 第一章开始安卓和 Java 差不多,有一点我会指出来。

如果您有来自 第二章 *的项目,第一联系人:Java,XML,以及 UI 设计器,*打开,选择文件 | 新建 | 新建项目… 。或者,如果您在 AndroidStudio 欢迎屏幕上,选择开始一个新的 AndroidStudio 项目。然后,进行如下操作:

  1. 选择项目模板窗口,选择空活动。这和我们在 第一章开始安卓和 Java 做的有点不一样。 ** 在配置您的项目屏幕中,将名称字段更改为Empty Activity App。* 剩下的设置可以保留默认值,点击完成即可。*

*AndroidStudio 将生成所有代码和其他项目资源。现在,我们可以在项目浏览器窗口中看到已经生成的内容,并将其与我们已经知道的内容联系起来。

如果仿真器还没有运行,选择工具 | AVD 管理器启动仿真器,然后在你的虚拟设备窗口启动你的仿真器。通过点击快速启动栏中的播放按钮,在模拟器上运行应用,就像我们在之前的项目中已经做了几次的那样。

看看这个应用,注意它和第一个项目有一点不同。它是——嗯——空的:顶部没有菜单;底部没有浮动按钮。然而,它仍然有一些文字说你好世界!,如下图截图所示:

Figure 3.1 – Hello world!

图 3.1–你好,世界!

现在我们有了一个全新的空活动项目,让我们来探索一下 Android Studio 为我们生成的文件和文件夹。

探索一个空的活动项目

现在,是时候深入了解我们应用的文件和文件夹了。这将为我们节省大量的时间,并在本书的后面挠头。但是,请注意,不需要记住所有这些文件的位置,更不需要理解文件中的代码。事实上,即使在本书的结尾,XML 的某些部分仍然是一个谜,但这不会阻止你设计、编码和发布惊人的应用。

在下面的截图中,查看项目资源管理器窗口,就在项目创建之后:

Figure 3.2 – Project Explorer window

图 3.2–项目浏览器窗口

注意到上一张截图中的两个箭头了吗?正如你可能猜到的,这些允许我们展开appGradle Scripts文件夹。您的文件夹可能已经展开。为什么不试试箭,然后展开和折叠几次呢?

注意

我们不需要在本书的上下文中探究Gradle Scripts文件夹。Gradle 是 AndroidStudio 的重要组成部分,但它的作用是向用户隐藏 AndroidStudio 执行的相当复杂的过程——比如添加资源文件、编译和构建项目。因此,我们不需要进一步深究。然而,如果你决定让安卓更上一层楼,那么很好地了解 Gradle 及其与 AndroidStudio 的关系是一项时间投资。

我们将详细探讨app文件夹。点击app文件夹旁边的箭头展开其内容,我们开始探索。第一级内容显示在下面的截图中:

Figure 3.3 – Exploring the app folder

图 3.3–浏览应用文件夹

我们又展示了四个文件夹:manifests``java``java(generated)res。让我们看看所有四个,从顶部开始。

注意

Packt 图书使用的样式指南建议这种字体用于用户屏幕上出现的文本,而this font用于文件名和文件夹名。由于我们正在讨论的文件和文件夹既是文件又是文件夹,并且出现在屏幕上,为了保持一致性,我选择了仅使用后一种字体,因为它更紧凑,并且每当在整本书中选择不明确时,我都会使用这一选项。

清单文件夹

manifests文件夹里面只有一个文件。展开manifests文件夹,双击AndroidManifest.xml文件。请注意,该文件已在编辑器窗口中打开,并添加了一个选项卡,以便我们可以轻松地在该文件和其他文件之间切换回来。下一张截图显示了已经添加的新标签,以及包含在manifests文件夹内的AndroidManifest.xml文件中的 XML 代码:

Figure 3.4 – New tab added

图 3.4–添加了新选项卡

我们不需要理解这个文件中的所有内容,但是值得指出的是,我们会在这里偶尔进行修改——例如,当我们需要请求用户允许访问他们设备的功能时。当我们想要制作一个沉浸感的全屏应用时,我们也会编辑这个文件,比如在 第 21 章线程中启动的绘图应用和启动实时绘图应用

*请注意,文件的结构类似于我们在上一章中看到的布局文件的结构——例如,有以<section name开始并以</section name>结束的明确标注的部分。真实的例子有<application</application>,还有<activity</activity>

事实上,除了第一行,整个文件内容都被包装在<manifest</manifest>中。

就像我们在计算器中输入计算的括号一样,这些开始和结束部分必须匹配,否则文件会在我们的项目中导致错误。AndroidStudio 在行前缩进(放置标签),以使这种结构中的部分及其深度更加清晰。

这段代码的几个特定部分值得注意,所以我将指出其中的一些行。

接下来显示的一行告诉安卓,我们希望在用户的应用抽屉/主屏幕中向用户显示的启动应用的图标包含在mipmap文件夹中,称为ic_launcher:

android:icon="@mipmap/ic_launcher"

当我们继续探索时,我们将亲自验证这一点。

下一行有两个方面值得讨论。首先,它表示我们给我们的应用起的名字;其次,这个名字包含在一个标签为app_name字符串中,如下图所示:

android:label="@string/app_name"

注意

在编程中,包括 Java 和 XML,字符串是任何字母数字值的。我们将从第 7 章 、 Java 变量、运算符和表达式开始,在整本书中学习更多关于字符串的内容。因此,我们可以猜测app_name标签的字母数字值是Empty Activity App,因为这就是我们创建应用时所说的。

这听起来可能有点奇怪,但是我们很快就会看到这个文件(以及它的标签),并且在以后的项目中,我们会给它添加更多的标签和值。我们也将逐渐理解为什么我们在应用中添加文本的原因,这在现阶段可能看起来相当复杂。

我们可以讨论AndroidManifest.xml文件中的每一行,但我们不需要。让我们再看两个,因为它们是相互关联的。下一行显示了我们的活动名称,这是我们创建项目时 AndroidStudio 选择的。我在这里突出了活动名称,只是为了让它更突出:

<activity android:name=".MainActivity">

出现在<activity</activity>标签中的下一行表示它是activity的一个属性,并显示该活动是应用启动时应该运行的活动。是LAUNCHER:

<category android:name="android.intent.category.LAUNCHER" />

这意味着我们的应用可以有多个活动。很多时候,如果你的应用有多个屏幕——比如主屏幕、设置屏幕等等——它们是由多个Activity实例构建的。

关于Activityactivity的一个注记。在 XML 中,与AndroidManifest文件一样,activity是小写的,但是在 Java 中,Activity类是大写的A。这只是惯例,没什么好担心的。正如我们刚刚看到的,XML 中的activity有一个name属性,其值引用了一个 Java Activity的实例。

让我们深入java文件夹。我想知道我们会在那里找到什么。

java 文件夹

我为这个略带讽刺的评论道歉。当然,我们会找到所有的 Java 代码。首先,它只包含一个文件,但是随着项目的增长,我们会添加更多的文件。展开java文件夹,会发现还有三个文件夹,如下图截图所示:

Figure 3.5 – Expand the java folder

图 3.5–展开 java 文件夹

在这本书里,我们只需要这三个文件夹中的一个——最上面的那个。这些文件夹的名称由包名(在我们创建应用时选择)和应用名组成,全部小写,没有空格(在我们创建应用时也选择)。

注意

有多个同名文件夹的原因是出于与自动化测试相关的高级原因,这超出了本书的范围。因此,您可以放心地忽略以(androidTest)(test)结尾的文件夹。

在这本书的过程中,我们唯一感兴趣的文件夹是最上面的一个,对于这个应用(在我的屏幕上)来说是com.gamecodeschool.emptyactivityapp。根据您选择的软件包名称和我们当前正在使用的应用的名称,文件夹名称将会更改,但它将始终是我们需要访问和添加(或编辑)内容的首选。

现在展开com.gamecodeschool.emptyactivityapp(或者你的名字)文件夹查看它的内容。在下一张截图中,您可以看到该文件夹只有一个文件:

Figure 3.6 – com.gamecodeschool.emptyactivityapp folder

图 3.6–com . gamecode school . emptyactivityyapp 文件夹

这个文件是MainActivity.java,尽管文件扩展名没有显示在项目窗口中,即使它在编辑器窗口上方的选项卡中。事实上,java/packagename.appname文件夹中的所有文件都有一个.java扩展名。如果双击文件,它将在编辑器窗口中打开,尽管我们可以单击编辑器窗口上方的MainActivity.java选项卡。随着我们添加更多的 Java 文件,知道它们保存在哪里将会很有用。

检查MainActivity.java文件,您将看到它是我们在第一个项目中使用的 Java 文件的简化版本。除了onCreate方法的方法少,自动生成的代码少之外,都是一样的。方法缺失是因为 UI 比较简单,所以不需要,AndroidStudio 也没有生成。

作为参考,请看下一张截图中MainActivity.java文件的内容。我概述了代码中的一行:

Figure 3.7 – MainActivity.java file

图 3.7–MainActivity.java 文件

它还有用户运行 app 时执行的onCreate方法,但是里面的代码少了很多,onCreate是唯一的方法。看看onCreate方法中的最后一行代码——在继续探索res文件夹之前,我们将讨论这一点。下面是正在讨论的代码行:

setContentView(R.layout.activity_main);

代码正在调用一个名为setContentView的方法,并且正在将一些数据传递到setContentView方法中,以供setContentView方法中的代码使用。传递给setContentView的数据是R.layout.activity_main

目前我只提一下setContentView方法是安卓应用编程接口 ( API )提供的,是为用户准备和显示 UI 的方法。那么,R.layout.activity_main到底是什么?

我们将通过浏览res文件夹找到答案,但是快速提及Java (generated)文件夹,这样我们就不会在前进的过程中遇到麻烦。首先要注意的是,该文件夹是第一次在模拟器或真实设备上运行应用时自动生成的,因此如果您没有运行该应用,您将看不到它。

Java(生成的)文件夹

这个文件夹包含 AndroidStudio 生成的代码,我们不需要关心里面有什么。即使是可能需要它的高级用户,一般也只是作为参考。

让我们进入res文件夹和那个R.layout.activity_main代码。

res 文件夹

res文件夹是所有资源的去处。左键点击展开res文件夹,我们会检查里面是什么。以下是此文件夹中最上层文件夹的截图:

Figure 3.8 – res folder

图 3.8–RES 文件夹

让我们从列表顶部开始,从drawable文件夹开始。

资源/可绘制文件夹

这个名字给了一些东西,但是drawable文件夹保存的不仅仅是图形。当我们阅读这本书时,我们确实会在这个文件夹中添加图形。然而,现在,它只保存了两个文件。

这些文件是ic_launcher_foregroundic_launcher_background。我们不会检查任何一个文件,因为我们永远不需要修改它们,但我只会提到它们是什么。

如果你打开这些文件,你会发现它们很长,而且技术性很强。除此之外,它们还包括坐标、颜色等列表。它们就是所谓的图形遮罩,安卓系统使用它来调整/遮罩其他图形——具体来说,就是这个应用的启动器图标。这些文件向安卓提供了如何调整应用启动器图标的说明。

这个系统是可以使用的,这样不同的设备制造商可以创建自己的面具来适应自己的安卓设备。默认情况下位于drawable文件夹(ic_launcher_foregroundic_launcher_background中)的蒙版是默认的自适应蒙版,为启动器图标添加视觉上令人愉悦的阴影和深度。

注意

如果你对自适应图标的概念感兴趣,那么你可以在安卓开发者网站的链接上看到一个完整且非常直观的解释。您不需要看到此页面就可以继续。

目前我们对drawable文件夹已经了解得够多了,所以让我们进入layout文件夹。

资源/布局文件夹

res文件夹是你的应用的所有资源都在这里,比如图标、布局(XML 文件)、声音和字符串。让我们仔细看看。

展开layout文件夹,会看到一个名为activity_main.xml的布局文件,如果打开查看它的内容,会看到和我们上一章编辑的很像。这次少了一些,因为我们生成了一个空活动项目。它并不完全是空的,因为它仍然包含一个ConstraintLayout元素,包装了一个表示Hello World!TextView小部件。

一定要看内容,但这不是这里最有趣的。仔细查看文件的名称(没有 XML 文件扩展名):activity_main

现在,回想一下MainActivity.java文件中的 Java 代码。下面是我们说的设置用户界面的代码行。我强调了代码的一部分:

setContentView(R.layout.activity_main);

R.layout.activity_main代码确实是对res/layout文件中activity_main文件的引用。这是我们的 Java 代码和我们的 XML 布局/设计之间的联系。

注意

除了activity_main.xml的内容之外,与第一个项目有所不同——在第一个项目的layout文件夹中,有多个附加文件。本章稍后,我们将使用第一章中使用的相同模板(基本活动)来构建另一个项目,以了解原因。

在此之前,让我们探索一下最后的两个文件夹及其所有子文件夹,从列表中的下一个开始:mipmap

res/mipmap 文件夹

mipmap文件夹很简单——嗯,相当简单。展开文件夹查看其内容,如下图所示:

Figure 3.9 – mipmap folder

图 3.9–MIP map 文件夹

在这里,我们可以看到两个子文件夹:ic_launcheric_launcher_roundic_launcher的内容是我们在设备的应用抽屉/主屏幕中看到的常规启动器图标的图形,ic_launcher_round包含使用圆形图标的设备的图形。双击每个文件夹中的一个.png文件进行查看。在下一张截图中,我对每张图片都进行了 Photoshopped 处理,以帮助我们的讨论:

Figure 3.10 – Launcher icons

图 3.10–启动器图标

你可能也想知道为什么每个文件夹里有五个ic_launcher….png文件。这样做的原因是,为不同的屏幕尺寸和分辨率提供适当缩放的图标是一种良好的做法。通过提供具有hdpimdpixhdpixxhdpixxxhdpi资格的图像,这允许不同的安卓设备选择最适合用户的图标。

注意

字母dpi代表每英寸hmxhxxhxxxh前缀代表高、中、特高、特高等等。这些被称为限定符,随着我们的进步,我们将看到安卓有很多限定符,可以帮助我们构建应用,以适应各种不同的安卓设备。

mipmap文件夹的最后一个难题是两个子文件夹中的每一个都有一个 XML 文件。打开其中一个,您会看到它们引用了我们在drawable文件夹中查看的ic_launcher_foregroundic_launcher_background文件。这告诉安卓设备从哪里获得自适应图标的细节。这些文件不是必需的,但它们使图标看起来更好,并增加了外观的灵活性。

我们还有一个文件夹及其所有文件,然后我们将很好地理解一个安卓应用的结构。

res/values 文件夹

打开res/values文件夹,展示三个文件,我们将依次简单介绍。所有这些文件相互链接/引用和/或我们已经看到的其他文件。

为了完整起见,这里是res/values文件夹中三个文件的截图:

Figure 3.11 – res/values folder

图 3.11–分辨率/数值文件夹

注意

values文件夹里面还有一个themes文件夹,但是我们不需要在本书的上下文中去探究这个。

理解的关键不在于记忆连接,当然也不在于试图记忆甚至理解文件中的代码,而在于欣赏到我们迄今为止所看到的所有文件和代码的相通性。

让我们一次浏览一个文件。

colors . XML 文件

接下来我们来看看colors.xml文件的内容,如下:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="colorPrimary">#6200EE</color>
    <color name="colorPrimaryDark">#3700B3</color>
    <color name="colorAccent">#03DAC5</color>
</resources>

请注意,开始和结束标记采用了我们从 XML 文件中得到的常见模式。有一个开始<resources>标签和一个结束</resources>标签。作为资源的孩子,有三对<color> … </color>标签。

在每个color标签中有一个name属性和一个奇怪的代码,由数字和字母组成。name属性是一种颜色的名称。我们将在后面的另一个文件中看到不同的名称。

代码本身就是定义实际颜色的东西。因此,当提到名称时,相关代码定义的颜色就是屏幕上产生的颜色。我们一会儿就会看到这些名字指的是哪里。

注意

该代码被称为十六进制代码,因为在代码的每个位置,可以使用值09af,给出 16 个可能的值。如果你想了解更多,用十六进制颜色在周围玩,请访问http://www.color-hex.com/color-wheel/。如果你对十六进制(以 16 为基数)、二进制(以 2 为基数)等数字基数感兴趣,那么看看下面这篇解释它们的文章,谈谈为什么人类通常使用 10 为基数:https://betterexplained.com/articles/numbers-and-bases/。你不需要浏览这些文章来继续阅读这本书。

字符串. xml 文件

大多数现代应用都是为尽可能多的受众制作的。此外,如果一个应用有很大的规模或复杂性,那么软件公司中的角色通常被分成许多不同的团队——例如,为安卓应用编写 Java 代码的人很可能与设计用户界面的布局没有什么关系。

通过将应用的内容与应用的编程分开,可以更容易地随时进行更改,并且还可以为多种不同的口语创建内容,而无需更改每种语言的 Java 代码。

看看strings.xml文件的内容,转载如下:

<resources>
    <string name="app_name">Empty Activity App</string>
</resources>

我们可以看到在现在熟悉的<resources>…</resources>标签中,我们有一个<string>…</string>标签。在string标签中,有一个名为name的属性,它有一个app_name值,然后还有一个Empty Activity App值。

让我们再看一行我们之前在货单文件夹部分浏览过的AndroidManifest.xml文件。下面是有问题的那一行,但是如果你想看到完整上下文中的那一行,请参考 AndroidStudio 中的文件本身:

android:label="@string/app_name"

android:label属性被赋予一个值@string/app_name。在安卓系统中,@string指的是strings.xml文件中的所有字符串。在这个特定的应用中,app_name标签的string属性有一个Empty Activity App值。

因此,之前显示的AndroidManifest.xml文件中的代码行在应用运行时对屏幕有以下影响:

Figure 3.12 – AndroidManifest.xml file effect

图 3.12–androidmanifest . XML 文件效果

虽然一开始这个系统看起来很复杂,但实际上它将设计和内容从编码中分离出来,这是非常有效的。如果一个应用的设计者想改名字,只需编辑strings.xml文件,不需要和 Java 程序员交互;如果应用中的所有文本都是作为字符串资源提供的,那么随着项目的进行,所有文本都可以很容易地更改和调整。

安卓通过允许开发人员为每种语言/地区的字符串资源使用不同的文件,进一步提高了这种灵活性。这意味着开发人员可以用完全相同的 Java 代码来迎合一个充满快乐用户的星球。一个 Java 程序员只需要引用一个字符串资源的name属性,而不是将文本本身硬编码成 Java,然后其他部门就可以设计文本内容,处理语言翻译等任务。我们将在 第 18 章本地化中制作一个多语种的 app。

注意

可以直接将实际的文本硬编码到 Java 代码中,而不是使用字符串资源,有时我们会这样做,以便轻松显示一些 Java,而不会因编辑或添加到strings.xml文件而陷入困境。在上一章中,当我们制作吐司消息并将文本输出到控制台时,我们做到了这一点。

安卓系统允许设计师选择颜色、文本、图像、声音和其他资源,并轻松为世界不同地区制作不同的应用。

比如在西方文化中,绿色可以代表自然、正确等主题;在许多中东国家,绿色代表生育能力,是与伊斯兰教相关的颜色。虽然你可能会在这两个地区分发绿色产品,但你的应用会有很大不同。

如果你把你的应用推广到印尼,绿色在很多印尼人(虽然不是所有人)的文化中是被鄙视的。接下来,你在中国推出,绿色有潜在的负面含义,与不忠的配偶有关。这是一个典型的 Java 程序员永远不会学会导航的雷区——幸运的是,由于我们可以在 AndroidStudio 中划分责任的方式,他们不需要了解这一点。

颜色——以及风格和主题——是一个非常专业的话题。虽然我们不会比快速进军绿色领域更深入地探索,但希望您能看到将编程、布局、颜色和文本内容的责任分开的系统的好处。

还值得一提的是,生产一款能被成千上万——甚至数百万——用户享受的出色应用,而不需要单独迎合每个地区,这是完全可能的。然而,即使我们不打算雇佣设计师、翻译和文化专家团队,我们仍然必须在这个为他们设计的系统中工作,这就是我们如此深入的原因。

在这个阶段,我们已经很好地掌握了安卓项目的内容以及不同方面是如何联系在一起的。让我们再构建一个应用,不是详细介绍它,而是看看不同的应用模板对 AndroidStudio 生成的底层文件的不同之处。

探索基本活动项目模板的文件和文件夹结构

具有自动生成的用户界面的第二简单的项目类型是基本活动项目。这是我们在 第一章 中创建的同类型项目,开始安卓和 Java 。现在请随意打开这个项目,但是生成一个新的项目也一样快,然后我们也可以检查它,而不会有任何我们的修改和添加影响讨论。

进行如下操作:

  1. 运行 AndroidStudio,左键点击开始一个新的 AndroidStudio 项目选项。

  2. 接下来的窗口是选择项目模板窗口。选择基本活动,点击下一步

  3. In the Configure Your Project window, set up the project as follows:

  4. 点击完成按钮,我们将运行应用,看看我们取得了什么成就。

现在,我们可以深入研究这些文件。我们不会像在空活动项目中那样查看中的所有细节;相反,我们将只查看文件的相互关联性,并进行一些比较。

探索基础活动项目

我们先来看看代码编辑器中MainActivity.java选项卡中的 Java 代码。如前所述,一个基本活动项目比一个空活动项目更有意义。

注意

你可以打开任意多的 AndroidStudio 实例。如果要并排比较项目,选择文件 | 打开然后选择项目,出现提示时选择新建窗口打开项目,不关闭任何已经打开的项目。

首先要注意的是onCreate方法中有一些额外的代码。

MainActivity.java 档案

我在第二章 *【第一次接触:Java、XML 和用户界面设计器】*中非常简要地提到了这些在 Java 代码和 XML 代码中的相互连接。让我们浏览一下资源文件,指出这段 Java 代码指向的 XML 文件。

下面是显示的 Java 代码。我稍微修改了格式,使它在书中更易读:

Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
FloatingActionButton fab = findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
   @Override
   public void onClick(View view) {
         Snackbar.make(view, "Replace with your own 
          action", Snackbar.LENGTH_LONG)
                      .setAction("Action", null).show();
   }
});

要完全理解这段代码将需要更多的章节,但是指出这段代码在资源中使用文件的地方只需要一点时间,然后会让我们更加了解组成我们项目的组件。

代码引用了两个资源。第一个是Toolbar资源,通过R.id.toolbar引用。第二个是FloatingActionBar资源,指的是我们将很快通过R.id.fab看到的 XML 文件。

如果我们在项目窗口中打开res/layout文件夹和java文件夹,我们可以看到事情看起来与在空活动项目中的情况不同,如下图所示:

Figure 3.13 – res/layout folder and java folder

图 3.13–RES/layout 文件夹和 java 文件夹

现在有三个自动生成的 Java 文件,四个自动生成的 XML 布局文件。

请记住,该应用有两个屏幕——第一个屏幕带有 Hello first fragment 消息和 Next 按钮;和第二个屏幕,它只是有一个先前的按钮。

正在发生的事情是,AndroidStudio 不仅为每个屏幕的外观提供了单独的布局文件,而且还为控制每个屏幕的代码提供了单独的 Java 文件。如果你从表面上看我刚才说的,你会期望两个布局文件和两个 Java 文件,但是我们有更多。

我们已经知道,当用户运行 app 时,会执行MainActivity.java文件的onCreate方法。这将设置应用,包括布局。布局在activity_main.xml但是这个文件不再控制两个主屏幕的布局。它具有两个屏幕之间一致的元素,并将布局委托给content_main.xmlcontent_main.xml文件定义了它所占据的屏幕区域,并将出现在该区域的细节委托给另一个文件,即res/navigation文件夹中的nav_graph.xml文件。该nav_graph.xml文件然后确定使用哪个布局(fragment_first.xmlfragment_second.xml)以及哪个对应的 Java 文件将控制该布局(FirstFragment.javaSecondFragment.java)。

在这个阶段,明显的回旋可能是压倒性的。我的猜测是,这是学习安卓开发而没有任何以前的开发经验会如此具有挑战性的事情之一。但好消息是:

  • 我们不需要记住和理解所有这些相互联系的细节。
  • 我们可以构建大量的应用,而无需使用任何一个。
  • 当我们阅读这本书并处理这个难题的不同部分时,我们将一次一个地熟悉它们。

请看下图,图中显示了基本活动模板应用的工作原理:

Figure 3.14 – Basic Activity template

图 3.14–基本活动模板

如果表面上的复杂性看起来令人沮丧,那么理解它为什么这样做可能会有所帮助。我们已经讨论过将布局从编程中分离出来,并进一步分离出文本和图形,以允许不同的团队处理应用的不同方面。现在,我们不仅可以进一步分离应用不同屏幕之间的导航,比如主菜单屏幕、设置屏幕和其他一些屏幕,而且由于与每个屏幕相关的布局和编程是独立的,它们也可以由不同的团队同时工作。随着章节的深入,我们会了解更多。

我们将从 第 24 章设计模式、多个布局和片段开始,研究编码独立的片段布局和控制每个布局的独立 Java 代码,并了解我们为什么要这样做,我们将在下一章更深入地挖掘互连的布局文件,如activity_main.xmlcontent_main.xml

现在,让我们更深入地看看MainActivity.java文件代码是如何与activity_main.xml布局链接的。我们会看到虽然activity_main.xml文件负责放置工具栏和浮动动作按钮,但是MainActivity.java文件负责控制当用户与它们交互时会发生什么。

activity_main.xml 文件

现在打开activity_main.xml文件,你会看到有一些元素同时代表toolbarfab。引用这些元素的 Java 代码正在设置准备使用的工具栏和浮动操作栏。正如我们所料,XML 代码描述了它们的样子。

下面是工具栏的 XML 代码:

<androidx.appcompat.widget.Toolbar
   android:id="@+id/toolbar"
   android:layout_width="match_parent"
   android:layout_height="?attr/actionBarSize"
   android:background="?attr/colorPrimary"
   app:popupTheme="@style/AppTheme.PopupOverlay" />

请注意,它指的是工具栏、颜色和样式,以及一些其他方面。

为清晰起见,这是实际工作应用中的工具栏:

Figure 3.15 – Toolbar of the app

图 3.15–应用的工具栏

下面是浮动操作按钮的 XML 代码。我将代码的第一行稍微重新格式化为两行,以便在本书的印刷版本中显示得更好:

<com.google.android.material.floatingactionbutton.
FloatingActionButton
   android:id="@+id/fab"
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:layout_gravity="bottom|end"
   android:layout_margin="@dimen/fab_margin"
   app:srcCompat="@android:drawable/ic_dialog_email" />

注意它的id值为fab。正是通过这个id值,我们可以访问 Java 代码中的浮动操作按钮——具体来说,就是MainActivity.java中的这一行:

FloatingActionButton fab = findViewById(R.id.fab);

这一行代码执行后,我们的 Java 代码中的fab对象现在可以直接控制浮动动作按钮及其所有属性。在 第 13 章匿名类–将安卓小部件带入生活中,我们将详细学习如何做到这一点。

这是实际应用中的浮动操作按钮:

Figure 3.16 – Floating action button

图 3.16–浮动操作按钮

我没有详细解释代码,因为这个阶段没有意义。开始在脑海中记下这些相互联系,如下所述:

  • XML 文件可以引用其他 XML 文件。
  • Java 可以引用 XML 文件(我们很快就会看到,也可以引用其他 Java 文件)。
  • 现在,我们已经看到,在 Java 中,我们可以通过其id属性获取对 XML 文件中用户界面特定部分的控制。

我们已经从这个文件中看到了足够多的内容,所以让我们继续深入研究剩余的文件。

MainActivity.java 的额外方法

那么方法是做什么的,什么时候调用,由谁调用?下一个不同之处是这个额外的方法(同样,为了演示稍微重新格式化):

@Override
public boolean onCreateOptionsMenu(Menu menu) {
   // Inflate the menu; this adds items to the 
   // action bar if it is present.
   getMenuInflater().inflate(R.menu.menu_main, menu);
   return true;
}

这段代码准备(膨胀)在menu_main.xml文件中定义的菜单,就像onCreate方法一样,onCreateOptionsMenu方法是一个被覆盖的方法,由操作系统直接调用。

然后,还有另一种方法,如下所示:

@Override
public boolean onOptionsItemSelected(MenuItem item) {
   // Handle action bar item clicks here. The action bar 
      will
   // automatically handle clicks on the Home/Up button, so 
      long
   // as you specify a parent activity in 
      AndroidManifest.xml.
   int id = item.getItemId();
   //noinspection SimplifiableIfStatement
   if (id == R.id.action_settings) {
         return true;
   }
   return super.onOptionsItemSelected(item);
}

这个方法也被覆盖了,它也被操作系统直接调用。它处理当用户从菜单中选择一个项目(选项)时发生的情况。目前,它只处理一个选项,即设置选项,目前,它不采取任何行动,如下所示:

The code if (id == R.id.action_settings) {

这将确定是否点击了设置菜单中的任何选项,如果点击了这些选项,return true代码将执行,并且控制将返回到用户点击设置菜单选项而中断之前正在执行的应用的任何部分。

目前我们知道的已经够多了。不要担心记住所有这些联系。我们将回到每一个联系,更深入地调查,巩固我们对每一个的理解。

现在,我们可以仔细看看安卓模拟器。

探索安卓模拟器

随着我们的进步,准确熟悉如何使用安卓模拟器会有所帮助。如果你没有使用最新版本的安卓系统,一些执行简单任务的方式(例如查看所有应用)可能会与你当前设备的工作方式不同。此外,我们想知道如何使用所有仿真器附带的额外控件。

仿真器控制面板

您可能在运行模拟器时注意到了模拟器旁边出现的迷你控制面板。让我们来看看一些最有用的控件。看这个模拟器控制面板的截图。我对它进行了注释,以帮助讨论:

Figure 3.17 – Emulator control panel

图 3.17–仿真器控制面板

下面我就只提一下比较明显的控制,必要的时候再深入一点:

  1. 这些是窗口控件。最小化或关闭模拟器窗口。
  2. 从上到下,关闭仿真器,模拟关闭实际设备的电源。接下来的两个图标会提高和降低音量。
  3. 这两个按钮允许您左右旋转模拟器。这意味着您可以测试您的应用在所有方向上的外观,以及它如何在应用运行时处理方向变化。紧挨着下面的图标分别截图和放大。
  4. 这些图标模拟了后退按钮和主页按钮,以及查看正在运行的应用。玩一玩这些按钮,因为我们需要不时地使用它们,包括在 第 6 章安卓生命周期中。
  5. 按下此按钮启动高级设置菜单,在这里您可以与进行交互,例如传感器、全球定位系统 ( GPS )、电池、指纹识别器等等。如果你好奇的话,可以玩一玩这些设置。

让我们玩一玩模拟器本身。

将仿真器用作真实设备

模拟器可以模拟真实手机的每一个功能,因此可以用它写一本关于的书。如果你想写你的用户喜欢的应用,那么了解一系列安卓设备是非常值得花时间去做的。我只想在这里指出一些最基本的特性,因为如果没有这些基本的交互,就很难跟得上这本书。此外,如果你有一个旧的安卓设备,那么一些基本的东西(比如访问应用抽屉)已经改变了,你可能会有点困惑。

访问应用抽屉

按住主屏幕底部的鼠标光标,向上拖动即可访问应用抽屉(所有应用)。下面的截图显示了此操作的一半:

Figure 3.18 – Drag upwards to access app drawer

图 3.18–向上拖动进入应用抽屉

现在,您可以运行模拟器上安装的任何应用。请注意,当您通过 AndroidStudio 运行您的应用之一时,它仍然安装在模拟器上,因此可以从应用抽屉中运行。然而,您在 AndroidStudio 中对应用所做的每一个更改都需要您通过单击 AndroidStudio 快速启动栏上的播放按钮来再次运行/安装应用——就像我们一直在做的那样。

查看活动应用并在应用之间切换

要查看活动的应用,您可以使用模拟器控制面板,模拟器控制面板截图上标记为数字 4 的方块(图 3.17 )。要使用手机屏幕访问相同的选项(就像在真正的设备上一样),向上滑动,就像访问应用抽屉一样,但只能在大约四分之一的屏幕长度内这样做。下面的截图说明了这一过程:

Figure 3.19 – Swipe up

图 3.19–向上滑动

您现在可以左右滑动浏览最近的应用,向上滑动应用以关闭它,或者点击后退按钮以返回到您查看该选项之前正在做的事情。一定要尝试一下,因为我们会经常使用这些基本功能。

总结

还记得本章的目标是熟悉安卓系统/结构/一个安卓项目吗?安卓项目有时是 Java 和大量资源文件的复杂交织。资源文件可以包含 XML 来描述我们的布局、文本内容、样式和颜色,以及图像。可以针对世界上不同的语言和地区制作资源。我们将在整本书中看到和使用的其他资源类型包括主题和音效。

记住不同资源文件和 Java 文件相互连接的所有不同方式并不重要。重要的是要意识到它们是,并且能够检查各种类型的文件,并意识到它们何时依赖于另一个文件中的代码。每当我们创建从 Java 代码到 XML 代码的连接时,我总是会再次指出连接的细节。

我们不需要像学习 Java 一样学习 XML,但是我们会对它有一点熟悉。Java 将是本书的重点,但是我们的 Java 将经常引用 XML 代码,所以理解并看到一些互连的例子将对您取得更快的进步大有裨益。

我们还探索了模拟器,以便在测试我们的应用时充分利用它。

在下一章中,我们将使用两种不同的安卓布局方案构建两种自定义布局。我们还将编写一些 Java 代码,这样我们就可以通过点击按钮在它们之间进行切换。***