Android Studio 学习手册(一)

打印 上一主题 下一主题

主题 532|帖子 532|积分 1596

原文:Learn Android Studio
  协议:CC BY-NC-SA 4.0
  一、Android Studio 简介

本章将引导您安装和设置您的开发环境,以便您可以遵照本书中的示例和实行。起首,您将安装一个名为 Java 开发工具包(JDK)的必备组件。然后,您将下载并安装 Android Studio 以及 Android 软件开发工具包(SDK),这是构建 Android 应用所需的一套软件工具。我们将向您展示如何使用 New Project 领导来创建一个名为 HelloWorld 的简单项目。最后,我们将向您展示如何建立到 Android 假造设备(AVD)和物理 Android 设备的连接。本章结束时,你将拥有在 Android Studio 中开始开发应用所需的一切。
在 Windows 上安装 Java 开发工具包

本节适用于 Windows 用户。如果您是 Mac 用户,请跳到“在 Mac 上安装 Java 开发工具包”一节 Android Studio 使用 Java 工具链进行构建,因此在开始使用 Android Studio 之前,您需要确保您的盘算机上安装了 Java 开发工具包(JDK)。很有大概你的电脑上已经安装了 JDK,尤其是如果你是一个履历丰富的 Android 或 Java 开发职员。如果您的盘算机上已经安装了 JDK,并且运行的是 1.6 版或更高版本,那么您可以跳过这一部分。但是,您大概照旧想下载、安装和配置最新的 JDK。您可以从以下 Oracle 站点下载 JDK:
www.oracle.com/technetwork/java/javase/downloads/index.html
当你登岸这个页面时,点击 Java 下载按钮,如图 1-1 所示。

图 1-1。
The Java Download button on the Java Downloads page
在 Windows 上下载 JDK

如图 1-2 所示,安装的下一步要求您通过单击 Accept License Agreement 单选按钮担当许可协议。然后,您必须为您的操作系统选择符合的 JDK。如果你运行的是 Windows 7 或 Windows 8,你应该点击 Windows x64 标签右边的文件链接,也如图 1-2 所示。Oracle 经常对 JDK 进行版本更新。到本书付印时,几乎可以肯定的是,JDK 的新版本将会推出,以是请务必下载最新版本。等待安装文件下载。这个文件通常在 125MB 左右,以是下载不会花很长时间。

图 1-2。
Accept the license agreement and click the appropriate link for Windows
在 Windows 上执行 JDK 领导

在安装 JDK 之前,在您的C:驱动器的根目次下创建一个名为Java的目次。这个目次的名字是任意的,尽管我们称它为Java,因为我们要在这里安装的许多工具都与 Java 相干,包括 JDK、Android Studio 和 Android SDK。将与 Android Studio 相干的工具一致地安装在C:\Java目次中也可以让您的开发环境保持有序。
导航到浏览器下载安装文件的位置,双击该文件执行安装。安装开始后,会出现安装领导,如图 1-3 所示。在 Windows 中,JDK 安装程序默认为C:\Program Files\Java\。要更改安装目次位置,请单击“更改”按钮。我们建议将您的 JDK 安装在C:\Java目次中,因为它的路径名中不包罗空格,而且容易记忆。见图 1-4 。

图 1-4。
Select the JDK installation directory

图 1-3。
Installation Wizard for the JDK on Windows
记下您安装 JDK 的位置。按照提示操作,直到安装完成。如果提示安装 Java Runtime Edition (JRE ),请选择安装 JDK 的目次。
在 Windows 上配置环境变量

本节将向您展示如何配置 Windows,以便 Android Studio 可以找到 JDK。在运行 Windows 的盘算机上,按住 Windows 键并按下 Pause 键打开系统窗口。点击高级系统设置选项,如图 1-5 所示。

图 1-5。
Windows System window
点击环境变量按钮,如图 1-6 所示。在底部的系统变量列表中,如图 1-7 所示,导航到JAVA_HOME项。如果JAVA_HOME项不存在,单击新建创建它。否则,单击编辑。

图 1-7。
Environmental variables

图 1-6。
System properties
点击新建或编辑表现类似图 1-8 的对话框。确保在变量名字段中输入JAVA_HOME。在变量值字段中,输入之前安装 JDK 的位置(去掉任何尾随斜线),如图 1-4 所示。现在点击确定。

图 1-8。
Edit the JAVA_HOME environmental variable
正如您对JAVA_HOME环境变量所做的一样,您将需要编辑PATH环境变量。见图 1-9 。将光标放在变量值字段的末端,并键入以下内容:

图 1-9。
Edit the PATH environmental variable
;%JAVA_HOME%\bin
现在,单击确定、确定、确定担当这些更改并退出系统属性。
要测试新的 JDK 是否已精确安装,请单击开始按钮,键入 cmd,然后按 Enter 键。
在命令行窗口中,发出以下命令并按 Enter 键:
java –version
如果您得到如图 1-10 所示的相应,那么恭喜您。您刚刚精确安装了 JDK。

图 1-10。
Confirm the proper JDK installation
在 Mac 上安装 Java 开发工具包

安装 Mac 版和 Windows 版 JDK 的前两步是雷同的。将您的浏览器指向以下站点:
www.oracle.com/technetwork/java/javase/downloads/index.html
当你登岸这个页面时,点击 Java 下载按钮,如图 1-11 所示。

图 1-11。
The Java Download button on the Java Downloads page
在 Mac 上下载 JDK

点击担当许可协议单选按钮,担当许可协议,如图 1-12 所示。然后,您必须为您的操作系统选择符合的 JDK。如果你运行的是 64 位版本的 OS X,你应该点击 Mac OS X64 标签右边的文件链接,也如图 1-12 所示。Oracle 经常对 JDK 进行版本更新。到本书付印时,几乎可以肯定的是,JDK 的新版本将会推出,以是请务必下载最新版本。等待安装文件下载。

图 1-12。
Accept the license agreement and click the appropriate link for Mac
在 Mac 上执行 JDK 领导

双击.dmg文件执行它。现在点击.pkg文件开始领导,根据需要点击继承,如图 1-13 到 1-15 所示。

图 1-15。
Installation success

图 1-14。
Installation Wizard

图 1-13。
JDK 8 Update 25.pkg
在 Mac 上配置 JDK 版本

要配置 Mac 以便 Android Studio 可以找到精确的 JDK,请打开 Finder 窗口并选取“应用”“➤实用工具”。在那边,打开 Java Preferences,并按照指示将新版本拖到列表的顶部,以便它被识别为首选版本。
安装 Android Studio

在开始下载 Android Studio 之前,为您将在本书中创建的 Lab 创建一个 Lab 父目次。我们在整本书中使用C:\androidBook\作为我们 Lab 的父目次,但是你可以选择或创建任何你认为符合的目次。因此,我们简单地称它为 labs 父目次。
下载 Android Studio 很简单。将您的浏览器指向此站点:
developer.android.com/sdk/installing/studio.html
现在点击绿色的下载 Android Studio for your OS 按钮,如图 1-16 所示。接下来,选中标志为“我已阅读并同意上述条款和条件”的复选框。再次单击 Download Android Studio for your OS,您的安装文件应该开始下载。下载完成后,执行刚刚下载的文件。

图 1-16。
Download Android Studio
安装领导开始后,通过单击“下一步”按钮浏览其屏幕,直到到达“选择组件”屏幕。在那边,选中所有组件复选框,如图 1-17 所示。然后单击下一步。再次同意条款和条件。当你进入配置设置:安装位置屏幕,如图 1-18 所示,选择 Android Studio 和 Android SDK 的位置。为了保持一致,我们选择在C:\Java\astudio\安装 Android Studio,在C:\Java\asdk\安装 Android SDK。

图 1-18。
Select locations for Android Studio and the SDK

图 1-17。
Choose components
安装 Android Studio 和 Android SDK 时,点击几个后续按钮。你应该最终到达完成 Android Studio 设置屏幕,如图 1-19 所示。“启动 Android Studio”复选框使 Android Studio 能够在您单击“完成”后启动。确保复选框被选中,然后点击 Finish,Android Studio 将启动。请注意,从现在开始,您需要导航到桌面图标或开始菜单来启动 Android Studio。

图 1-19。
Completing the Android Studio setup
当 Android Studio 第一次启动时,如图 1-20 所示,设置领导将分析您的系统,探求现有的 JDK(如您之前安装的那个),以及 Android SDK 的位置。设置领导应该下载你在 Android Studio 中开始开发应用所需的一切。单击“完成”按钮退出安装领导。

图 1-20。
Setup Wizard – Downloading Components
创建您的第一个项目:HelloWorld

一旦设置领导完成,欢迎使用 Android Studio 对话框出现,如图 1-21 所示。单击开始新的 Android 项目选项。

图 1-21。
Welcome to Android Studio
在出现的新建项目领导中(见图 1-22 ,在应用名称字段中键入 HelloWorld,在公司域字段中键入 gerber.apress.com。请注意,包名是反向公司域加上项目名。将 HelloWorld 项目安装在 labs 父目次的根目次下。如前所述,如果你运行 Windows,我们使用C:\androidBook\。如果您运行的是 Mac 或 Linux,您的 Lab 父目次名称不会以字母开头,而是以正斜杠开头。

图 1-22。
Configure your new project
Android 操作系统可以在许多平台上运行,包括游戏机、电视、手表、眼镜、智能手机和平板电脑。默认环境下,手机和平板电脑复选框将被选中,API-8 将被选为最低 SDK。担当这些设置,点击下一步,如图 1-23 所示。

图 1-23。
Select the form factors your app will run on
新建项目领导中的后续屏幕提示您选择布局。选择空白活动,然后单击下一步按钮。担当默认名称,如图 1-24 所示。它们应该如下:


  • 活动名称:主活动
  • 布局名称:活动 _ 主要
  • 标题:MainActivity
  • 菜单资源名称:menu_main

图 1-24。
Choose options for your new file
使用 Android 假造设备管理器

Android 假造设备管理器允许您创建 Android 假造设备(avd),然后您可以运行它来模拟您盘算机上的设备。模拟和仿真之间有一个重要但玄妙的区别。模拟意味着假造设备只是模拟实际物理设备举动的一个门面,但并不运行目标操作系统。iOS 开发环境使用模拟,考虑到该平台可用的设备数目有限,这大概是 iOS 的一个好选择。
但是,使用仿真时,您的盘算机会留出一块内存来再现仿真器正在仿真的设备上的环境。Android Studio 使用模拟,这意味着 Android 假造设备管理器启动 Linux 内核和整个 Android 堆栈的沙盒版本,以便模拟物理 Android 设备上的环境。尽管仿真提供了一个比模拟更可靠的环境来测试你的应用,但是启动 AVD 大概需要几分钟,这取决于你的电脑速度。好消息是,当您的模拟器在内存中激活后,它仍然可以相应。然而,如果你有安卓手机或平板电脑,我们建议使用物理设备来测试你的应用,而不是使用 AVD。也就是说,让我们起首使用 Android 假造设备管理器设置一个 AVD,在本章的后面,我们将向您展示如何连接您的物理设备,如果您有物理设备的话。
点击图 1-25 中圈出的 Android 假造设备管理器图标。在 Andriod 假造设备管理器领导的第一个屏幕上,单击创建假造设备按钮。在下一个屏幕上,如图 1-26 所示,选择 Galaxy Nexus 并点击下一步。下一个屏幕如图 1-27 所示,允许您选择系统图像。为 ABI 为 x86_64 的 Lollipop(或最新的 API)选择第一个选项。单击下一步。在下一个屏幕上,单击完成按钮验证您的 AVD 设置。恭喜你,你刚刚创建了一个新的 AVD。

图 1-27。
Select the x86_64 system image

图 1-26。
Select the Galaxy Nexus hardware

图 1-25。
AVD icon Note
x86_64 版本需要英特尔硬件加快,它只能在有限数目标英特尔芯片组上运行。如果您实行安装 x86_64 并且失败,请实行 armeabi-vxx 版本。
Tip
如果您想要为 Android Studio 还没有设备界说的设备创建 AVD,我们建议您前往 phonearena.com 并搜索您的型号。在那边你可以找到技术规范,你可以用它来创建一个新的设备界说。创建新的设备界说后,使用雷同的步骤创建新的 AVD。
市面上有一款优秀的第三方 Android 模拟器,叫做 Genymotion。Genymotion 模拟器是免费的,用于非商业目标,性能非常好。解释如何设置和使用 Genymotion 超出了本书的范围,但是你可以从 genymotion.com 下载 Genymotion 模拟器。
在 AVD 上运行 HelloWorld

要在新创建的 AVD 上运行你的 HelloWorld 应用,点击工具栏上绿色的 run 按钮,如图 1-28 所示。

图 1-28。
Run button
确保选择了 Launch Emulator 单选按钮,然后在组合框中选择 Galaxy Nexus API 21。点击确定,如图 1-29 所示。请耐心等待,因为启动 AVD 大概需要几分钟时间。你现在应该看到你的 HelloWorld 应用在你电脑的一个窗口中运行,如图 1-30 所示。

图 1-30。
Emulator screenshot

图 1-29。
Choosing a device and launching the emulator
在 Android 设备上运行 HelloWorld

如前所述,虽然 avd 对于模拟特定设备很有用,尤其是那些你手头没有的设备,但在物理 Android 设备上开发应用更受欢迎。如果当您通过 USB 电缆将 Android 设备连接到您的电脑时,您的电脑无法识别您的 Android 设备,您大概需要 USB 驱动程序。如果您的盘算机最初识别您的 Android 设备,您大概应该放弃安装差别或更新版本的 USB 驱动程序,因为这大概会导致 USB 连接失败。
Note
Mac 和 Linux 用户通常不需要下载 USB 驱动程序来在其 Android 设备和盘算机之间建立 USB 连接。
您可以使用developer.android.com/tools/extras/oem-usb.html#Drivers处的表格来查找符合的 USB 驱动程序,或者使用您喜欢的搜索引擎来查找适用于您的型号的 USB 驱动程序。下载驱动程序并安装在您的盘算机上。在 Android 设备上,点击设置,然后点击开发者选项。确保选中了 USB 调试复选框。有些设备(如 Samsung 设备)需要暗码才华启用 USB 调试,因此您大概希望使用您最喜欢的搜索引擎来研究如何在您的设备上启用 USB 调试。如果这个过程不是很明显的话,YouTube 也是一个很好的视频来源,可以教你如何在你的特定设备上启用 USB 调试。
大多数 Android 设备都配有一根电缆,一端有一个 USB 插头,另一端有一个微型 USB 插头。使用此电缆将您的 Android 设备连接到电脑。点击图 1-31 中圈出的 Android 设备监控按钮。如果驱动程序安装精确,你应该看到设备在那边列出并连接,如图 1-32 所示。

图 1-32。
Android Device Monitor screen showing the connected physical device

图 1-31。
Android Device Monitor button Note
请记着,您的盘算机和 Android 设备之间的连接是通过使用一个名为 Android Debug Bridge (ADB)的服务器建立的。如果看不到该设备,请单击 IDE 左下角的终端按钮,并发出以下命令:
adb start-server
如果重新启动 ADB 服务器后,您仍然看不到该设备,虽然大概性不大,但 USB 驱动程序需要重新启动系统才华生效。
现在点击绿色的运行按钮(如之前图 1-28 所示)。选择连接的 Android 设备。在图 1-33 中,连接的设备是 HTC One X Android 智能手机。点击 OK,等待几秒钟,你会看到 HelloWorld 在你的 Android 设备上运行。

图 1-33。
The Choose Device screen with the physical Android device listed
摘要

在这一章中,你安装了 Java 开发工具包,或 JDK,你也安装了 Android Studio 和 Android SDK。您使用新建项目领导创建了一个名为 HelloWorld 的简单应用。然后你创建了一个 Android 假造设备,或 AVD。我们向您展示了如何安装任何所需的 USB 驱动程序。最后,我们向您展示了如何在 AVD 和物理 Android 设备上启动 HelloWorld。现在,您应该已经拥有了在 Android Studio 中开发 Android 应用所需的所有软件。
二、导航 Android Studio

Android Studio 是一个窗口环境。为了最大限度地使用有限的屏幕空间,并防止你不知所措,Android Studio 在任何时候都只表现一小部分可用窗口。其中一些窗口是上下文相干的,只有在上下文符合时才会出现,而其他窗口则保持隐蔽,直到您决定表现它们,或者相反,保持可见,直到您决定隐蔽它们。为了充分使用 Android Studio,您需要了解这些窗口的功能,以及如何和何时表现它们。在这一章中,我们将向你展示如何在 Android Studio 中管理窗口。
任何集成开发环境(IDE)的根本功能之一就是导航。Android 项目通常由许多包、目次和文件组成,一个中等复杂程度的 Android 项目大概包罗数百个这样的素材。您使用 Android Studio 的效率将在很大程度上取决于您在这些素材中导航的舒服程度。在本章中,我们还将向您展示如何在 Android Studio 中导航。
最后,我们将向您展示如何使用 Android Studio 中的资助系统。为了充分使用本章,打开我们在第一章中创建的 HelloWorld 项目。如果这个项目已经在 Android Studio 中打开,您就可以开始了。当我们讨论以下导航功能时,请参考图 2-1 。

图 2-1。
Android Studio’s integrated development environment
编辑

任何 IDE 的主要目标都是编辑文件。正如所料,允许用户在 Android Studio 中编辑文件的窗口位于 IDE 的中央窗格。编辑器窗口在窗口中是唯一的,因为它总是可见的,并且总是位于中心窗格。究竟上,编辑器窗口是 Android Studio 的一个非常广泛的特性,从现在开始,我们将它简称为编辑器。Android Studio 中的所有其他窗口被称为工具窗口,聚集在编辑器周围的侧窗格(左侧、底部和右侧)中。
编辑器是一个选项卡式窗口,在这方面,它类似于当代的 web 浏览器。当您从其中一个工具窗口、键盘快捷方式或上下文菜单中打开文件时,该文件将表现为编辑器的一个选项卡。正如您在构建第一个项目 HelloWorld 时已经发现的那样,MainActivity.java和activity_main.xml文件会作为标签自动加载到编辑器中。Android Studio 试图猜测您大概会开始编辑哪些文件,然后在完成新建项目领导后,自动在编辑器中以标签情势打开它们。几乎任何文件都可以在编辑器中打开,尽管原始图像和声音文件还不能在 Android Studio 中编辑。您也可以将文件从工具窗口拖放到编辑器上;这样做可以在编辑器中将文件作为选项卡打开。
编辑器顶部是编辑器标签。沿着编辑器的左边界是装订线,沿着编辑器的右边界是标志栏。让我们依次检查每一个。
编辑器选项卡

要在 Android Studio 的编辑器选项卡中导航,请使用 Alt+右箭头键| Ctrl+右箭头键或 Alt+左箭头键| Ctrl+左箭头键。固然,你可以用鼠标选择一个编辑器标签。编辑器选项卡的选项位于➤编辑器选项卡窗口的主菜单栏中。从该菜单中选择的任何操作都适用于当前选定的选项卡。将鼠标滚动到MainActivity.java选项卡上,右键单击(在 Mac 上按住 Ctrl 键单击)它。在产生的上下文菜单中,如图 2-2 所示,您会注意到许多与您在窗口➤编辑器选项卡中发现的选项雷同的选项。从该上下文菜单中,选择选项卡放置子菜单。菜单选项“上”、“下”、“左”和“右”允许您移动标签栏。向右或向左移动标签栏可以容纳更多可见的标签,尽管这是以牺牲屏幕空间为代价的。

图 2-2。
Editor tab context menu
编辑器选项卡上下文菜单的关闭和关闭所有操作非常简单。当您想要关闭除活动标签之外的所有标签时,可以使用“关闭其他标签”操作。“垂直拆分”和“水平拆分”操作用于将编辑器细分为多个窗格。如果您想并排比较两个文件,垂直拆分特别有用。您可以无限分割窗格,尽管这种嵌套分割的效用会很快减少。您还可以将文件从其他窗口拖放到编辑器的任何窗格,或者从一个窗格拖放到另一个窗格。关闭窗格的最后一个选项卡会导致整个窗格消失。
阴沟

装订线用于转达关于代码的信息。也许 gutter 最明显的特性是小色板和图像图标表现在引用这些视觉资源的相应代码行旁边。装订线还用于设置断点、方便代码折叠和表现范围指示器。所有这些特性将在随后的章节中具体介绍。
标志栏

编辑器右侧是标志栏。标志栏用于指示源文件中重要行的位置。例如,标志栏突出表现 Java 或 XML 文件中的警告和编译时错误。标志栏还表现未提交的更改、搜索结果和书签的位置。
标志栏不会像装订线那样滚动;相反,标志栏上的彩色暗号是相对于文件的长度定位的。单击标志栏中的彩色勾号会立即跳转到文件中的该位置。现在,通过单击标志栏上的一些彩色标志来训练使用标志栏。
工具按钮

您已经看到了默认环境下表现在左侧窗格中的项目工具窗口。要查看所有工具窗口的列表,请从主菜单栏中选择查看➤工具窗口。现在仔细观察 IDE 的左、右和下边缘。在那边,您可以找到与许多工具窗口相对应的工具按钮。请注意,其中一些工具按钮还标有数字,该数字与 Alt(Mac 上的 Cmd)键联合使用,以打开/关闭该工具按钮对应的工具窗口。现在实行单击工具按钮来训练这项技能。还要训练使用快捷键 Alt+1 | Cmd+1、Alt+2 | Cmd+2、Alt+3 | Cmd+3 等等来切换工具窗口的打开/关闭。
当工具窗口打开时,相应的工具按钮是暗灰色的,表示它被按下。请注意,工具按钮位于页边距的角上。例如,“项目”工具按钮的默认位置在左边距的右上角,而“个人收藏”工具按钮默认位于左边距的左下角。
侧窗格(左侧、底部和右侧)一次最多可以由两个工具窗口共享。要查看如何共享侧窗格,请同时打开收藏夹和项目工具窗口。请注意,“个人收藏”和“项目”工具按钮位于同一页边空白的对角。如果两个工具窗口的对应工具按钮位于同一角落,则实行在这两个工具窗口之间共享侧窗格将不起作用。例如,项目和布局工具窗口不能同时表现——至少在 Android Studio 的默认配置中不能。
默认布局

不要混淆 Android Studio 中的默认布局和 Android SDK 中的布局。默认布局是聚集在编辑器周围的一组特定的工具窗口。Android Studio 配置为开箱即用,默认布局在左侧窗格中表现项目工具窗口。这是之前在图 2-1 中表现的布局。
让我们来看看主菜单栏中的窗口菜单。前两个菜单项是将当前布局存储为默认布局和规复默认布局。“规复默认布局”操作通常在 IDE 变得过于拥挤时使用,或者您只想清除白板并返回到熟悉的布局。您也可以自界说默认布局,方法是打开和关闭您喜欢的任何工具窗口,调整它们的大小和/或位置,然后通过选择“将当前布局存储为默认值”将该新布局设置为默认布局。
Repositioning Tool Buttons
如上所述,项目和布局工具窗口不能同时表现,因为它们对应的工具按钮位于同一角落。但是,您可以将任何工具按钮移动到您想要的任何角落。将“布局”工具按钮拖放到左边距的左下角。现在,通过使用键盘快捷键 Alt+1 | Cmd+1 和 Alt+7 | Cmd+7 或通过单击它们的工具按钮来切换项目和布局工具窗口打开。因为我们将它们的工具按钮移动到对角,以是项目和布局工具窗口现在可以共享同一个侧窗格并同时表现。
导航工具窗口

本节讨论专门用于导航的工具窗口:项目、布局、收藏夹、待服务项和命令。表 2-1 列出了每个导航工具窗口的功能。后续章节涵盖了许多其他工具窗口。
表 2-1。
Navigation Tool Windows
| 工具窗口 | 电脑钥匙 | Mac 密钥 | 功能 | | --- | --- | --- | --- | | 项目 | Alt+1 | Cmd+1 | 允许您在项目中导航文件和资源 | | 收藏夹 | Alt+2 | Cmd+2 | 表现收藏夹、书签和断点 | | 布局 | Alt+7 | Cmd+7 | 表现当前文件中对象或元素的分层树 | | 指挥官 |   |   | 类似于项目工具窗口,但允许轻松管理文件 | | 待服务项 |   |   | 表现项目中所有活动待服务项的列表 | 项目工具窗口

我们发现项目工具窗口是最有用的导航工具窗口,因为它联合了广泛的范围和相对容易的访问。要了解项目工具窗口的功能和范围,您大概需要将窗口的模式设定为项目。有三种模式;项目、包和 Android。默认环境下,Android Studio 会将模式设置为 Android。Android 和 Project 是最有用的模式,尽管 Android 模式大概会对你隐蔽某些目次。模式设置组合框位于 90 度角,靠近 IDE 左上角的项目工具按钮。项目工具窗口提供了一个简单的树状界面,其中包罗可以切换的文件和嵌套目次。“项目工具”窗口提供了项目中所有包、目次和文件的概述。如果在“项目工具”窗口中右键单击(在 Mac 上按住 Ctrl 键单击)某个文件,将会出现一个上下文菜单。此上下文菜单中有三个重要的菜单项:复制路径、文件路径和在资源管理器中表现。单击复制路径将操作系统到该文件的绝对路径复制到剪贴板。单击文件路径会将路径表现为一堆目次,文件位于顶部,单击这些目次中的任何一个都会在操作系统中打开它们。单击“在资源管理器中表现”会在操作系统的新窗口中表现该文件。参见图 2-3 。

图 2-3。
The Project tool window
布局工具窗口

“布局工具”窗口表现文件中元素的层次布局。当编辑器表现一个 Java 源文件如MainActivity.java时,布局工具窗口表现一个元素树,如字段、方法和内部类。当编辑器表现一个 XML 文件(如activity_main.xml)时,布局工具窗口会表现一个 XML 元素树。单击布局工具窗口中的任何元素都会立即将光标移动到编辑器中的该元素。布局工具窗口对于在大型源文件中的元素间导航特别有用。通过打开布局工具窗口并在MainActivity.java和activity_main.xml的元素间导航来训练这项技能。见图 2-4 。

图 2-4。
The Structure tool window
收藏夹工具窗口

在 Android 中开发一个特性(或调试一个 bug)时,您大概会创建或修改几个相干的文件。中等复杂程度的 Android 项目大概包罗数百个单独的文件,因此将相干文件分组的本领确实很有用。“收藏夹”工具窗口包罗收藏夹,这些收藏夹允许您对相干文件的引用进行逻辑分组,否则这些文件大概位于项目中完全差别的部分。
确保MainActivity.java和activity_main.xml文件都作为标签加载到编辑器中。现在右键单击(在 Mac 上按住 Ctrl 键)编辑器中的任一选项卡,并从上下文菜单中选择“全部添加到收藏夹”。在输入新的收藏夹列表名称字段中,键入 main,然后按确定。如果收藏夹工具窗口未打开,请通过切换 Alt+2 | Cmd+2 来激活它。展开名为 main 的收藏夹项目,双击其中列出的一个文件将其打开/激活。
就像“收藏夹”窗口允许您立即导航到任何特定的文件或文件组一样,书签允许您立即导航到文件中的任何特定行。将光标定位在MainActivity.java中的任意一行。现在按 F11(在 Mac 上按 F3)。这项动作会在任何来源档案(包括 XML 档案)中建立或移除书签。请注意槽中的勾号和标志栏中指示新书签的黑色勾号。要查看刚刚创建的书签,请在收藏夹工具窗口中切换打开书签。
Note
在 PC 上,如果 F11 好像没有相应,请检查以确保键盘上的 F-Lock 键已被激活。
断点用于调试。与可以在任何文件中设置的书签差别,您需要在 Java 源文件中设置断点。打开MainActivity.java并点击下一行代码旁边的空白处:
setContentView(R.layout.activity_main);
您会注意到一个赤色的圆圈现在占据了檐槽,并且这条线也被突出表现为赤色。只能在可执行代码行上设置断点;例如,试图在注释行上设置断点是行不通的。若要查看新创建的断点,请在收藏夹工具窗口中切换打开断点树。你可以用断点做几件更风趣的事情,我们在专门讨论调试的第十二章中具体讨论了断点。
待服务项工具窗口

TODO 的意思固然是做。TODOs 本质上是向程序员和他们的合作者表明另有工作要做的注释。TODO 的写法类似于注释,以两个正斜杠、全大写的 TODO 和一个空格开始。例如:
//TODO inflate the layout here.
在MainActivity.java中创建一个待服务项,打开待服务项工具窗口查看。单击 TODO 工具窗口中的 TODO 会立即跳转到源代码中的该 TODO。
管理器工具窗口

“管理器工具”窗口是一个导航辅助工具,有左右两个窗格。这些窗格的功能与项目和布局工具窗口非常相似。Commander 工具窗口与其他导航窗口的差别之处在于,它一次只表现一个目次级别,而不是表现嵌套的目次树。如果您更喜欢 Windows 风格的导航,或者您发现项目工具窗口太大,那么 Commander 工具窗口大概是一个不错的导航选择。
主菜单栏

主菜单栏是 Android Studio 中最上面的栏,你可以通过浏览它的菜单和子菜单来执行几乎任何操作。与 Android Studio 中的其他栏差别,主菜单栏无法隐蔽。不要被主菜单栏及其子菜单中包罗的浩繁操作所淹没。即使是最有履历的 Android 开发职员天天也只会使用这些操作中的一小部分,而且大多数操作都有相应的键盘快捷键和/或上下文菜单项。我们将在后续章节中讨论主菜单栏中包罗的许多操作。
工具栏

工具栏包罗常用文本操作的按钮,如剪切、复制、粘贴、撤消和重做。正如你已经在第一章中看到的,工具栏还包罗了 Android Studio 中各种管理器的按钮,包括 SDK 管理器和 Android 假造设备管理器。工具栏另有用于设置和资助的按钮,以及用于运行和调试应用的按钮。工具栏中的所有按钮都有相应的菜单项和键盘快捷键。高级用户大概希望通过取消选中“查看➤工具栏”菜单项来隐蔽工具栏,以节省屏幕空间。
导航栏

导航栏表现一系列水平箭头框,代表从项目根目次(左侧)到编辑器中当前选定选项卡(右侧)的路径。导航栏可用于导航项目资源,而无需求助于项目或管理器工具窗口。
状态栏

状态栏如图 2-5 (之前在图 2-1 中)所示,表现相干的和上下文敏感的反馈,例如关于任何运行的进程或者你的项目标 Git 库的状态的信息。现在让我们更具体地研究一下状态栏。

图 2-5。
Status bar
状态栏的最左边是“切换边距”按钮。单击此按钮可切换隐蔽和表现页边距。别的,当您将鼠标悬停在此按钮上时,会出现一个上下文菜单,允许您激活任何工具窗口。
消息区域用于提供反馈并表现有关并发运行进程的任何信息。当您将鼠标滚动到 UI 元素(如工具栏中的菜单项或按钮)上时,该区域也会表现提示。单击此区域将打开变乱日志。
编辑器光标位置以行:列格式表现光标在编辑器中的位置。单击此区域会激活一个对话框,允许您直接导航到代码中的特定行。
行分隔符区域表现文本文件中使用的回车格式。在 Windows 上,默认为 CRLF,代表回车换行。LF 是 Unix 和 Mac 呆板上使用的标准格式,在 Git 中也是如此。如果您在 Windows 盘算机上进行开发,当您将代码提交到存储库时,Git 通常会从 CRLF 转换到 LF。
文本格式区域描述用于源文件的文本编码。缺省值是 UTF-8,它是 ASCII 的超集,包罗大多数西方字母,包括标准 Java 或 XML 文件中的任何字符。
文件访问指示器区域允许您在读/写和只读之间切换。未锁定的图标意味着编辑器中的当前文件具有读/写权限。锁图标表示编辑器中的当前文件是只读的。您可以通过单击指示器图标来切换这些设置。
“突出表现级别”按钮激活一个带有滑块的对话框,该对话框允许您设置希望在代码中看到的突出表现级别。
默认设置是 Inspections,它对应于皱眉的检查司理的图标。这个设置表明你应该预备好一些严厉的爱,因为检查司理将严酷识别语法错误和代码中大概的问题,称为警告。您可以在标志栏中看到由 Inspections Manager 生成的一些黄色标志。
滑块上的下一个设置是语法,它对应于配置文件中检查管理器的图标。对于这种设置,检查司理对警告视而不见。语法模式没有检查模式严酷,但仍然会突出表现会阻止代码编译的语法问题。
滑块上的最后一个突出表现模式是 None,它对应于一个微笑的检查司理的图标。这个图标让我觉得检查司理很开心,他根本不关心你的代码。在这种模式下,即使是最严峻的语法错误也会被忽略,尽管当您试图构建时,编译器仍然会被它们卡住。我建议把重点放在检查上,并学会欣赏检查司理的严厉的爱。
常见操作

本节回顾 Android Studio 中使用的各种常见操作。如果您使用过像 Microsoft Word 这样的文本编辑器,您大概会对本节中介绍的功能很熟悉。
选择文本

正如您对任何优秀的文本编辑器所期望的那样,双击源文件中的任何单词都会选中它。别的,在字母或单词上单击并拖动光标会选择这些文本元素。将光标放在源文件中的任意位置,然后按 Shift+下箭头键或 Shift+上箭头键选择从光标处开始的文本行。在一行文本的任意位置连按三次会选择整行。按 Ctrl+A | Cmd+A 选择文件中的所有文本。
如果将光标放在任何单词内并按 Ctrl+W | Alt+向上键,则整个单词都将被选中。如果您继承按 Ctrl+W | Alt+向上箭头键,所选内容将无限扩大,以包括相邻的文本。如果您现在按 Ctrl+Shift+W | Alt+向下箭头键,选择范围将缩小。这种增长/收缩选择功能在 Android Studio 中被称为布局化选择。
使用撤消和重做

“撤消”和“重做”命令对于回滚和前滚有限数目标编辑操作非常有用。更改由特定的 UI 变乱来限定,例如按 Enter 键或重新定位光标。撤消和规复的键盘快捷键分别是 Ctrl+Z | Cmd+Z 和 Ctrl+Shift+Z | Cmd+Shift+Z。在工具栏的左边有紫色的左右箭头也可以做到这一点。Android Studio 的默认设置是记着你上次生存的所有步骤,或者最多 300 步。打消和重做一次只应用于一个文件,以是回滚更改最有效的方法是使用 Git,这在第七章中讨论。
查找最近的文件

Android Studio 最好的特性之一是它能记着你最近处理过的所有文件。要激活此命令,请选择“查看➤最近的文件”或按 Ctrl+E | Cmd+E。出现的对话框允许您选择任何最近的文件,并在编辑器中将其作为选项卡打开。默认限制是最多记忆 50 个以前的文件。您可以通过导航到文件➤设置➤限制➤编辑器➤最近的文件限制来更改这些限制。
遍历最近的导航操作

Android Studio 还会记着你最近的导航操作。导航操作包括光标移动、选项卡更改和文件激活。若要遍历导航操作历史记载,请按 Ctrl+Alt+左箭头键| Cmd+Alt+左箭头键或 Ctrl+Alt+右箭头键| Cmd+Alt+右箭头键。请记着,导航操作差别于编辑操作;如果你想遍历你的编辑操作,你应该使用打消和重做。
剪切、复制和粘贴

如果你使用过任何文本编辑器或文字处理器,你应该熟悉剪切、复制和粘贴。表 2-2 列出了这些根本命令,以及一些扩展的剪贴板命令。
表 2-2。
Cut, Copy, and Paste
| 命令 | 电脑钥匙 | Mac 密钥 | | --- | --- | --- | | 切口 | Ctrl+X | Cmd+X | | 复制 | Ctrl+C | Cmd+C | | 粘贴 | Ctrl+V | Cmd+V | | 扩展粘贴 | Ctrl+Shift+V | Cmd+Shift+V | | 复制路径 | Ctrl+Shift+C | Cmd+Shift+C | | 复制参考 | Ctrl+Alt+Shift+C | Cmd+Alt+Shift+C | 除了操作系统剪贴板提供的简单剪切、复制和粘贴功能,Android Studio 另有一个扩展的剪贴板,可以记着最近五次剪切和复制操作。当你从 Android Studio 中剪切或复制文本时——或者在 Android Studio 运行时从几乎任何其他应用中剪切或复制文本时——Android Studio 会将这些文本放到一个堆栈中。要查看扩展的剪贴板堆栈,请按 Ctrl+Shift+V | Cmd+Shift+V。出现的对话框允许您选择要粘贴的项目。参见图 2-6 。

图 2-6。
Extended clipboard
您还可以通过导航到文件➤设置➤限制➤编辑器➤剪贴板中保留的最大内容数来更改扩展剪贴板堆栈的大小。您也可以通过右键单击所选内容并选择“与剪贴板比较”菜单项,将任何当前选定的文本与扩展剪贴板中最新元素的文本进行比较。
“复制路径”命令 Ctrl+Shift+C | Cmd+Shift+C 复制在“项目”或“管理器”工具窗口或编辑器的任何选项卡中选择的任何文件或目次的完全限定的操作系统路径。复制路径对于终端会话中的操作特别有用。
使用复制引用 Ctrl+Alt+Shift+C | Cmd+Alt+Shift+C,Android Studio 允许您复制对方法、变量或类的逻辑引用。当您将这个引用粘贴到另一个源文件中时,Android Studio 会自动包罗任何须需的包限定符和导入。您还可以在“项目”和“管理器”工具窗口中对包、目次和文件使用通用的剪切、复制和粘贴来代替鼠标操作(如拖放),以便重新组织资源在项目中的位置。
上下文菜单

在 IDE 上右键单击(在 Mac 上按住 Ctrl 键单击)可以激活许多上下文菜单。您已经在上一节中探索了编辑器选项卡上下文菜单。Android Studio 中的大多数窗格、图标和栏都会生成一个上下文菜单,如果你右击它(在 Mac 上是 Ctrl-click)。Android Studio 最大的特点之一是动作可以用多种方式执行。这种冗余意味着你可以根据自己的喜欢自由发展自己的技能和习惯。我发现对最频仍的操作使用键盘快捷键,对不太频仍的操作使用菜单和上下文菜单操作是与 Android Studio 交互的最有效方式。现在,通过右键单击(在 Mac 上按住 Ctrl 键单击)IDE 中的栏、选项卡、窗格和文件来浏览上下文菜单。
获得资助

Android Studio 中的资助菜单有几个有用的菜单项。find Action(Ctrl+Shift+A | Cmd+Shift+A)是你在 Android Studio 中获取资助最常用的命令。该命令会激活一个对话框,允许您在 Android Studio 中搜索任何功能。按 Ctrl+Shift+A | Cmd+Shift+A 并在搜索框中键入表现行号。现在使用箭头键选择设置,并按下回车键。在设置窗口中,选择编辑器➤外观。您应该看到“表现行号”复选框。
选择资助➤在线文档是你的所有 Android Studio 技术规范的来源。这是 Android Studio 最全面的文档。别的,资助➤默认键映射参考菜单项是一个有用的参考。当你学习使用 Android Studio 时,你可以考虑打印这个 PDF 文件并把它放在附近。
使用键盘导航

键盘大概是在 Android Studio 中导航的最强大的方式。从主菜单栏中选择导航菜单以检查其内容。本节讨论导航菜单中最重要的菜单项(如表 2-3 所示)及其相应的键盘快捷键。后续章节讨论其他菜单项。
表 2-3。
Keyboard Navigation
| 命令 | 电脑钥匙 | Mac 密钥 | | --- | --- | --- | | 在中选择 | Alt+F1 | Alt+F1 | | 班级 | Ctrl+N | Cmd+O | | 文件 | Ctrl+Shift+N | Cmd+Shift+O | | 线条 | Ctrl+G | Cmd+L | | 相干文件 | Ctrl+Alt+Home | alt+Cmd+向上箭头 | | 上次编辑位置 | ctrl+Shift+退格键 | cmd+Shift+退格键 | | 范例层次布局 | Ctrl+H | Ctrl+H | | 申报 | Ctrl+B | Cmd+B | 在中选择

Android Studio 最好的一个特性就是导航是双向的。您已经看到了如何从各种工具窗口中打开/激活作为编辑器选项卡的文件。现在,您将学习如何从编辑器导航到各种工具窗口。
按 Alt+F1。这将激活“在上下文中选择”菜单,该菜单包罗几个菜单项,包括“项目视图”、“收藏夹”和“文件布局”。单击“项目视图”选项。项目工具窗口被激活,对应于编辑器的活动选项卡的文件被突出表现,并且该文件的任何父目次被切换打开。Android 项目每每有很多文件素材;因此,在中使用 Select 是您将掌握的最重要的技能之一。
班级

类操作允许您导航到特定的 Java 类。值得注意的是,这个操作只搜索 Java 源文件,或者 Java 源文件的内部类。按 Ctrl+N | Cmd+O,开始输入 act。Android Studio 已经为你的所有文件建立了索引,以是它会为你提供一个大概匹配的列表,最大概匹配的会高亮表现。你所需要做的就是按回车键打开MainActivity.java。
文件

文件操作允许您导航到项目中的任何文件。如果您正在项目中探求一个 XML 文件,这就是您想要使用的操作。按 Ctrl+Shift+N | Cmd+Shift+O,开始输入 act。我们特意使用了雷同的搜索术语 act 来说明“导航➤”文件的更大范围。注意,搜索结果包括 Java 源文件MainActivity.java以及任何其他文件,比如activity_main.xml。使用箭头键选择activity_main.xml并按 Enter 键打开它。
线条

行操作 Ctrl+G | Cmd+L 激活一个对话框,允许您导航到源文件的特定行:列。如果你在弹出的“转到第一行”对话框中输入一个简单的整数,然后按“确定”, Android Studio 会跳到那一行,而不考虑第几列。
相干文件

相干的文件动作 Ctrl+Alt+Home | Alt+Cmd+向上箭头是 Android Studio 中最有用的命令之一。Android 项目通常有很多相干文件。例如,一个简单的 Android 活动通常至少有一个相应的 XML 布局文件来出现活动的布局,另有一个相应的 XML 菜单文件来出现活动的菜单。当您处理片断时,这种复杂性只会增长。您已经看到了如何使用收藏夹将相干文件分组在一起。通过导航➤相干文件,你可以查询 Android Studio 来表现相干文件。激活MainActivity.java标签后,按 Ctrl+Alt+Home | Alt+Cmd+上箭头键。您应该会看到activity_main.xml列在那边。使用箭头键选择它,然后按 Enter 键。
上次编辑位置

最后一次编辑位置操作 Ctrl+Shift+back space | Cmd+Shift+back space 允许您导航到最后一次编辑。如果您继承激活此命令,光标将移动到您上次编辑的文件/位置,依此类推。
范例层次布局

Android 使用 Java,一种面向对象的编程语言。任何面向对象语言的标志之一是继承,这有利于代码重用和多态。当编辑器中的MainActivity.java文件处于活动状态时,按 Ctrl+H 切换打开层次工具窗口。在那边你会看到一系列层叠的对象,所有这些对象都可以追溯到 Java 中所有对象的祖先Object。请记着,只有当编辑器中的活动选项卡是 Java 源文件时,导航➤范例层次布局操作才有效。
申报

声明操作允许您跳转到方法、变量和资源的原始界说。激活此操作的另一种方法是按住 Ctrl|Cmd 键,同时将鼠标滚动到文件中的方法、变量或资源上。如果元素带有下划线,您可以通过在按住 Ctrl|Cmd 键的同时左键单击该元向来导航到它的声明。在MainActivity.java中,点击方法setContentView(...)中的任意位置,然后按 Ctrl+B | Cmd+B。您将立即被带到这个方法的声明,它位于MainActivity的一个超类ActionBarActivity.java中。
查找和替换文本

查找和替换文本是编程的一个重要部分,Android Studio 有一套强大的工具来资助你做到这一点。本节涵盖了一些最重要的工具。表 2-4 为你列出。
表 2-4。
Find and Replace
| 命令 | 电脑钥匙 | Mac 密钥 | | --- | --- | --- | | 发现 | Ctrl+F | Cmd+F | | 在路径中查找 | Ctrl+Shift+F | Cmd+Shift+F | | 替换 | Ctrl+R | Cmd+R | | 在路径中替换 | Ctrl+Shift+R | Cmd+Shift+R | 发现

Find 动作用于查找单个文件中出现的文本。在MainActivity.java中,按 Ctrl+F | Cmd+F 调出一个出现在编辑器顶部的搜索栏。在搜索栏的搜索框中键入 action。您会注意到action在整个文件中立即以黄色突出表现。您还会注意到标志栏中的绿色小暗号,指示找到的文本的位置。将鼠标滚动到查找栏上的双右箭头上会表现高级搜索选项。
在路径中查找

“在路径中查找”动作允许您在比前面描述的“查找”动作更大的范围内进行搜索。您也可以使用正则表达式,并用文件掩码分隔结果。按 Ctrl+Shift+F | Cmd+Shift+F,并在编辑器顶部搜索栏的搜索框中键入 hello。默认环境下,“查找路径”中的搜索范围设置为“整个项目”,尽管您可以将搜索范围限制为特定的目次或模块。担当缺省值“整个项目”,然后单击“查找”按钮。结果表现在“查找工具”窗口中。在“查找工具”窗口中单击一个条目会立即将包罗的文件作为编辑器的一个新选项卡打开,并跳转到该变乱。
替换

替换操作 Ctrl+R | Cmd+R 用于替换单个文件中的文本,替换功能是查找的超集。替换文本的更安全的方法是使用重构➤重命名命令,我们将在后面介绍。
在路径中替换

“在路径中替换”操作 Ctrl+Shift+R | Cmd+Shift+R 是“在路径中查找”的超集。然而,使用重构➤重命名几乎总是比在路径中使用替换更好,以是使用这个命令要非常小心,因为你大概会引入错误。
摘要

在本章中,我们已经讨论了编辑器和聚集在编辑器周围的工具窗口。我们已经讨论了如何使用工具按钮和重新定位它们。我们还讨论了用于导航的工具窗口和 IDE 的主要 UI 元素,包括主菜单栏、工具栏、状态栏、装订线和标志栏。我们还讨论了如何使用菜单和键盘快捷键,以及使用查找和替换来搜索和导航。最后,我们讨论了如何使用 Android Studio 中的资助系统。最重要的是,我们已经在 Android Studio 中建立了一个 UI 元素词典,我们将在后续章节中引用它。
三、在 Android Studio 中编程

本章报告了如何在 Android Studio 中编写和生成代码。Android Studio 使用其面向对象编程的知识来生成极其相干且格式良好的代码。本章涵盖的功能包括覆盖方法、用 Java 块困绕语句、使用模板插入代码、使用自动完成、注释代码和移动代码。如果你阅读这本书的目标是掌握 Android Studio,你会想要特别关注这一章,因为这里描述的工具和技术将对你的编程效率产生最大的影响。
我们开始吧。如果您在第一章中创建的 HelloWorld 应用尚未打开,请立即打开它。
使用代码折叠

代码折叠是节省编辑器屏幕空间的一种方式。代码折叠允许您隐蔽特定的代码块,以便您可以专注于您感兴趣的那些代码块。如果MainActivity.java没有打开,按 Ctrl+N | Cmd+O 并键入 Main 将其打开。按 Enter 键打开MainActivity.java类,如图 3-1 所示。

图 3-1。
Use the Enter Class Name dialog box to open MainActivity.java
如果默认环境下不表现行号,请导航以资助➤找到操作。键入表现行号并选择表现行号活动编辑器选项,如图 3-2 所示。

图 3-2。
Use the Enter Action or Option Name dialog box to show line numbers
当你观察MainActivity.java中的行号时,你会注意到一些奇怪的事情:行号不是一连的。在图 3-3 中,行号从 1、2、3 开始,然后跳到 7、8、9。仔细看图 3-3 中的第 3 行。您会注意到在 import 语句的左边有一个加号,后面有一个省略号。如果您仔细查看自己的代码,您还会注意到省略号以淡绿色突出表现。所有这些视觉元素都在告诉你,Android Studio 隐蔽了一段已经折叠的代码。

图 3-3。
Folded block of code at the import statement
一条称为折叠表面的细虚线位于左边距的长度方向,在灰色装订线和白色编辑器之间。折叠表面可以包罗三个图标:困绕在方框中的加号图标(如图 3-3 的第 3 行)和上下箭头,上下箭头内有水平线(见图 3-3 的第 12 行和第 15 行)。向下箭头表示可折叠代码块的开始,而向上箭头表示可折叠代码块的结束。如上所述,加号框表示代码块已经被折叠。单击这些图标中的任何一个都可以将相应的块切换到折叠或展开状态。表 3-1 包罗所有代码折叠操作的描述和键盘快捷键。
表 3-1。
Code-Folding Options
| [计]选项 | 电脑钥匙 | Mac 密钥 | 描述 | | --- | --- | --- | --- | | 发展 | ctrl+数字加 | cmd+数字加 | 展开光标所在的折叠块 | | 倒塌 | ctrl+数字-减号 | cmd+数字-减号 | 折叠光标所在的展开块 | | 全部展开 | ctrl+Shift+数字加 | cmd+Shift+数字加 | 展开窗口中的所有代码 | | 全部折叠 | ctrl+Shift+数字-减号 | cmd+Shift+数字-减号 | 折叠窗口中的所有代码 | | 切换折叠 | ctrl+句点 | cmd+句点 | 折叠/展开光标所在的块 | 将光标放在MainActivity.java的onCreate()方法内的任何地方。现在按频频 Ctrl+句点| Cmd+句点来切换此块的展开和折叠。还可以实行使用展开键盘快捷键 Ctrl+Numeric-Plus | Cmd+Numeric-Plus 和折叠键盘快捷键 Ctrl+Numeric-Minus | Cmd+Numeric-Minus。
最后,通过单击折叠表面中的代码折叠图标,使用鼠标切换折叠和展开的块。请记着,为了节省屏幕空间,折叠单个块、多个块乃至文件中的所有块只是将它们从视图中删除。然而,编译器仍然会在您构建时实行编译它们。同样,折叠包罗有问题或错误代码的块不会从标志栏中删除任何警告或错误。您可以通过选择菜单选项设置➤编辑器➤代码折叠来更改代码折叠选项。
执行代码完成

大多数当代 ide 都提供某种情势的代码完成,Android Studio 也不例外。Android Studio 随时预备提供资助,即使你没有主动寻求资助。在实践中,这意味着 Android Studio 会在你输入的时候默认建议各种选项来完成你的代码。Android Studio 生成的建议列表并不总是完美的,但是这些建议是根据最佳实践排序的,并且它们通常符符合当的命名约定。Android Studio 对 Android SDK 和 Java 编程语言都非常了解;究竟上,它大概比你更了解这些学科。如果你带着谦逊和渴望学习的态度来使用这个工具,不管你以前的编程履历如何,你最终都会看起来像一个摇滚明星。
代码完成特性是上下文相干的,因为根据光标的范围,提供给你的建议会有所差别。如果您在类范围内键入代码,代码完成建议将与您在方法范围内键入的建议差别。即使您选择不担当代码补全建议,出于上述原因,您也应该注意它们。
表 3-2 列出了 Android Studio 中的四种代码补全:
表 3-2。
Code-Completion Options
| [计]选项 | 电脑钥匙 | Mac 密钥 | 描述 | | --- | --- | --- | --- | | 默认 | 没有人 | 没有人 | 默认代码完成举动。Android Studio 会在您输入时在光标旁边表现一个建议列表。您可以使用上下箭头键在建议列表中的条目间导航,并使用 Enter 键选择一个条目。 | | 基础 | ctrl+空格 | ctrl+空格 | 根本代码完成功能类似于默认代码完成,但也在当前选定的条目旁边表现 Javadoc 窗口。单击 Javadoc 窗口中的向上箭头图标会表现具体的文档。 | | 智能范例 | ctrl+Shift+空格键 | ctrl+Shift+空格键 | SmartType 代码完成功能类似于 Basic,但会生成一个更具选择性和相干性的建议列表。 | | 循环扩展字 | Alt+/ | Alt+/ | 提供文档中已经使用过的单词。循环往复。 | | 循环扩展字(向后) | Alt+Shift+/ | Alt+Shift+? | 提供文档中已经使用过的单词。循环下降。 |

  • 一旦您开始键入,默认代码自动完成。
  • 根本代码完成的举动类似于默认代码完成,但还会在建议列表中当前所选项的旁边表现一个 Javadoc 窗口。
  • SmartType 代码完成也表现 Javadoc,但也生成更具选择性和相干性的建议列表。
  • 循环展开单词循环表现源文档中已经使用的单词,并允许您选择它们。
让我们开始编码来演示代码完成是如何工作的。右键单击(在 Mac 上按住 Ctrl 键)包com.apress.gerber.helloworld并选择新建➤ Java 类,弹出新建类对话框,如图 3-4 所示。将该类命名为 Sandbox,然后单击“确定”。

图 3-4。
Create New Class dialog box
在Sandox.java中Sandbox类的括号内,通过输入 private Li 开始界说成员,如图 3-5 所示。将出现一个代码完成菜单,其中列出了可供您完成代码的大概选项。使用上下箭头键导航代码完成菜单。用向下箭头键选择List<E>选项,然后按回车键。

图 3-5。
A code-completion menu appears when you start typing
Android Studio 中的默认举动是在开始输入时表现代码完成建议列表。您不需要激活任何键盘快捷键来调用默认代码完成—它会自动发生。你现在应该有一行代码表现为private List,如图 3-6 所示。直接在单词List后面,键入用于在 Java 中界说泛型的左尖括号(<)。请注意,Android Studio 用一个右尖括号来结束括号子句,并将光标放在括号内。

图 3-6。
Code completion of a list with String as the generic
在尖括号内键入 Str,然后按 Ctrl+Space 调用根本代码完成。您会注意到,在建议列表中当前选定的项目(String)旁边会出现一个 String Javadoc 窗口的文档。滚动 Javadoc 窗口查看String的 Javadoc 文档。单击 Javadoc 窗口中的向上箭头,在默认浏览器中表现String的具体 API 文档。返回 Android Studio,选择String作为通用类,通过按回车键界说List<String>时使用。
Android Studio 最好的特性之一就是它会为你建议变量名。在private List<String>后直接输入一个空格,按 Ctrl+Space 激活根本代码补全。Android Studio 生成了一个建议列表,但是没有一个变量名具有足够的描述性,以是改为键入 mGreetings。小写的m代表成员(也称为字段),在类成员名前面加上m是 Android 中的命名约定。同样,静态类成员的前缀是小写的s。您不需要遵照这种命名约定,但是如果您这样做,您的代码将更容易被他人明白。请记着,局部(方法作用域)变量不遵照m和s前缀命名约定。
修改您的代码行,使其现在表现为private List<String> mGreetings = new。通过按 Ctrl+Shift+Space 调用 SmartType 代码完成。选择ArrayList<>()完成该语句,包括终止分号,如图 3-7 所示。SmartType 代码完成类似于根本代码完成,只是在建议列表中生成项目时,它考虑的变量范围比默认和根本代码完成更广。例如,在赋值操作符的右侧使用 SmartType 代码完成时,建议列表通常会包罗相干的工厂方法。

图 3-7。
SmartType code completion Note
如果您在 Android Studio 中的 JDK 设置为 7 或更高,那么代码完成生成的代码大概会使用菱形符号。例如,ArrayList<String>大概以ArrayList<>的情势出现在使用泛型的赋值语句的声明的右侧,如图 3-7 所示。
循环展开词有个花里胡哨的名字,其实很简单。按住 Alt 键,同时按频频正斜杠,调用循环展开 Word。提供给您的单词与您的文档中出现的单词雷同。当你循环阅读单词时,注意黄色的高亮部分。现在通过按住 Alt 和 Shift 键同时按下正斜杠(Mac 上的问号)频频来调用循环向后展开单词。请注意,提供/突出表现的单词现在向下循环并远离光标,而不是向上循环并远离光标。
注释代码

如果你曾经做过任何编程,你就会知道注释是被编译器忽略的代码行,但是它包罗了对编码者和他们的合作者来说很重要的信息和元数据。注释可以是以两个正斜杠开始的行注释,也可以是以一个正斜杠和一个星号开始并以一个星号和一个正斜杠结束的块注释。从主菜单中,您可以通过选择代码➤注释来激活注释。然而,激活注释的最佳方式是使用表 3-3 中列出的键盘快捷键。
表 3-3。
Commenting Options
| [计]选项 | 电脑钥匙 | Mac 密钥 | 描述 | | --- | --- | --- | --- | | 切换注释行 | Ctrl+/ | Cmd+/ | 使用 Java 行注释样式(例如// …)在注释或取消注释之间切换行。您可以通过选择这些行将此操作应用于多行。 | | 切换注释块 | Ctrl+Shift+/ | Alt+Cmd+/ | 使用 Java 块注释样式(如/* … */)在注释块和未注释块之间切换选定的文本。将注释块应用到所选文本将包括注释块中的所有所选文本。 | 在mGreetings声明上方键入 refactor initial ization to constructor。按 Ctrl+/ | Cmd+/将此文本转换为注释,如图 3-7 所示。使用快捷键 Ctrl+/ | Cmd+/,实行打开和关闭此注释。
使用代码生成

如果使用得当,代码生成将会为您节省最多的时间。代码生成有本领为你生成各种各样的方法,包括构造器、getters、setters、equals()、hashCode()、toString(),等等。
在使用代码生成之前,让我们验证 Android Studio 是否被精确配置为忽略成员名前缀m和s。单击文件➤设置➤代码样式➤ Java ➤代码生成打开设置对话框,其中代码生成选项卡处于选中状态。如果字段和静态字段文本框没有分别包罗 m 和 s,现在在那边输入,点击应用,然后点击确定,如图 3-8 所示。

图 3-8。
Adding m and s to Field and Static Field in the Code Generation tab
构造器

将光标放在Sandbox.java的类范围内。要在 Android Studio 中生成构造函数,按 Alt+Insert | Cmd+N,选择构造函数。如图 3-9 所示,选择由构造函数初始化的字段对话框允许你选择类成员作为参数。我们需要一个无参数的构造函数,以是单击“不选”按钮。在 Java 中,重载构造函数以担当差别范例和数目标参数是很常见的。例如,您可以再次调用这个对话框,生成一个构造函数,它将一个List<String>作为参数,并将这个参数赋给我们的成员mGreetingsist<String>。

图 3-9。
Choose Fields to Initialize by Constructor dialog box
getter/setter

Java 类通常是封装的,这意味着类成员通常被声明为私有的,这些成员的公共接口是通过公共访问器(getter)和公共赋值器(setter)方法提供的。单击将光标放在Sandbox.java的类范围内,然后按 Alt+Insert | Cmd+N。您会注意到,有一个 Getter 选项,一个 Setter 选项,以及一个 Getter 和 Setter 选项。Getter 和 setter 方法通常是成对出现的,以是除非你有充分的理由省略其中的一个,否则最好同时生成两个方法。从列表中选择 Getter 和 Setter,如图 3-10 所示。在随后的“选择字段以生成 Getters 和 Setters”对话框中,从列表中选择mGreetingsist<String>并单击“确定”。你的类现在有了一个mGreetings的 getter 和 setter,如图 3-11 所示。注意,在生成方法名时,生成的代码忽略了前缀m,因为您在之前的设置中声明了前缀m和s。

图 3-11。
Generated getter and setter methods

图 3-10。
Generating the getter and setter
覆盖方法

代码生成明白类的层次布局,因此您可以覆盖任何超类或实现的接口中包罗的方法。Sandbox.java是一个简单明了的老式 Java 对象(POJO)。现在修改Sandbox类,使其扩展RectShape。当您键入 extends RectShape 时,单词RectShape大概会以赤色突出表现。如果是这种环境,按 Alt+Enter 导入RectShape类,如图 3-12 所示。

图 3-12。
Extending the superclass
如果您通过按 Ctrl+H 调用层次视图,您将看到以RectShape、Shape和Object为其祖先的Sandbox的类层次,正如您通过检查图 3-13 所看到的。现在按 Alt+Insert | Cmd+N 并选择覆盖方法。让我们从Shape开始覆盖hasAlpha()方法,如图 3-14 所示。从版本 Java 5 开始的惯例是用@Override注释被覆盖的方法,以是让我们保持 Insert @Override 复选框处于选中状态。@Override注释告诉编译器验证方法的名称和签名,以确保该方法确实被覆盖。修改hasAlpha()的返回语句,使其总是返回true。

图 3-14。
Modifying the hasAlpha( ) method

图 3-13。
Selecting methods to override/Implement with RectShape
toString()方法

Android Studio 可以为你生成toString()方法。让我们为Sandbox创建一个toString()方法,并包罗mGreetings成员。按 Alt+Insert | Cmd+N,选择toString()。选择您唯一的成员mGreetings,然后单击确定。Android Studio 生成一个返回字符串如"Sandbox{" + "mGreetings=" + mGreetings + '}',如图 3-15 。如果在我们的类中有多个成员并选择了它们,它们也会被附加到这个方法的返回字符串中。固然,toString()生成的代码并不是一成稳定的;您可以随意更改这个方法,只要它返回一个String。

图 3-15。
Generate the toString( ) method
委托方法

Android Studio 知道您的类成员,因此允许您将举动从类中界说的代理方法委托给类成员的方法。这听起来很复杂,但很简单。为了向您展示委托方法选项是如何工作的,让我们直接进入代码。
在Sandbox.java中,将光标放在类范围内。按 Alt+Insert | Cmd+N,然后选择委托方法。选择mGreetingsist<String>并按下 OK。List 接口有许多方法,您可以将举动委托给这些方法。为简单起见,选择add(object:E):boolean,如图 3-16 所示。如果您想要委托多个方法,请在选择这些方法时按住 Ctrl 键(Mac 上为 Cmd 键)。单击确定。

图 3-16。
Selecting methods to generate delegates
生成的add() methodin Sandbox.java现在是一个代理,将举动委托给mGreetings成员的add()方法,如图 3-17 所示。注意,add()方法的参数被界说为一个String,以匹配mGreetings的通用界说List<String>。委托方法不是被覆盖的方法,以是你可以把你的代理方法重命名为任何你想要的名字,但是名字add()很故意义,以是继承保持这个名字。

图 3-17。
Generated add( ) method
插入实时模板

Android Studio 附带了许多模板,允许您将预界说的代码直接插入到源文件中。在许多 ide 中,生成的代码只是从一个模板粘贴过来的,不考虑作用域;然而,Android Studio 的模板是范围感知的,也可以集成可变数据。
在您开始使用 Android Studio 中的实时模板之前,让我们探索现有的实时模板并创建一个我们自己的模板。导航到文件➤设置➤实时模板。选择普通模板组。现在单击右上角的绿色加号按钮,并选择 Live Template。添补缩写、描述和模板文本字段,如图 3-18 所示。在应用此模板之前,您必须单击 Define 按钮,该按钮看起来像窗口底部的蓝色超文本链接。现在选择 Java 并选择所有的作用域(语句、表达式、声明等等)。单击应用。

图 3-18。
Create a live template called cb (comment block)
您刚刚创建了一个名为cb的定制 live 模板,它在任何 Java 源文件和任何范围内编码时都是可用的。图 3-18 中的赤色字$SELECTION$为变量。您将很快看到这个变量的作用。现场模板选项在表 3-4 中描述。
表 3-4。
Live Template Options
| [计]选项 | 电脑钥匙 | Mac 密钥 | 描述 | | --- | --- | --- | --- | | 插入实时模板 | Ctrl+J | Cmd+J | 调用范围敏感的实时模板列表。将在您的文档中插入模板代码。 | | 用实时模板困绕 | Ctrl+Alt+J | Cmd+Alt+J | 使用实时模板列表调用范围敏感的困绕。将用一个范围敏感的实时模板困绕所选内容。 | 在离开实时模板的设置页面之前,快速浏览一下位于普通模板组中的一个现有实时模板,其缩写为 psfs。单击 psfs 检查其内容。您会注意到这个模板生成了一个带有public static final String的String常量,并且它只在 Java 和 Groovy 声明范围内可用。单击“确定”返回编辑器。
在Sandbox.java的声明部分,在mGreetings的界说下,键入 psfs,然后通过按 Ctrl+J | Cmd+J 调用实时模板,然后按 Enter。通过给该常量一个名称和赋值来完成该语句,如下所示:public static final String HELLO = " HELLO Sandbox ";。
Note
在 Java 中,常量的命名约定是全部大写。
在构造函数上方,键入单词 CONSTRUCTORS。现在将这个单词转换成一个注释块,以引起其他程序员的注意。选择整个单词,“构造函数”,然后按 Ctrl+Alt+J | Cmd+Alt+J 调用“用实时模板困绕”。在 Live Templates 列表中选择 cb,按回车键,如图 3-19 所示。您刚刚应用了之前创建的实时模板。

图 3-19。
Apply the live template called cb (comment block)
移动您的代码

Android Studio 了解代码块是如何分隔的,因此移动代码行或代码块既简单又直观。Move 语句和 Move Line 的区别在于,Move 语句同时考虑边界和范围,而 Move Line 则两者都不考虑。如果选择用 move 语句移动代码语句,该语句将保留在其封闭块范围的边界内。如果你用 Move Line 移动同一个语句,Android Studio 会把这个语句看成一个简单的文本行,并把它移动到你想要它去的任何地方。
您也可以移动整个代码块。使用 Move 语句,您只需将光标放在要移动的块的起始行(带大括号的行)上的任意位置,然后按 Ctrl+Shift+Down | Cmd+Shift+Down 或 Ctrl+Shift+Up | Cmd+Shift+Up。整个区块将一起移动,同时尊重其他区块的边界,并保持在其封闭范围的边界内。“移动行”不明白范围或边界,但在应用“上移行”或“下移行”操作之前,您仍然可以通过先选择它们来移动多行,这两种操作在 PC 和 Mac 上分别是 Alt+Shift+上移和 Alt+Shift+下移。
要明白 Android Studio 中的 move 操作,最好直接去做。让我们从在我们的add()方法中创建一个语句开始。在表现return mGreetings.add(object);的那一行之后,按 Enter 键开始新的一行,并键入 soutm。然后按 Ctrl+J | Cmd+J 调用 Live Template,产生System.out.println("Sandbox.add");。您大概已经注意到,您的新代码行将不会到达,因为 return 语句在它上面,如图 3-20 所示。让我们用 move 语句上移这个语句。按住 Ctrl|Cmd 和 Shift 的同时,多次按向上箭头键。Android Studio 重新定位该语句,但不会让您意外地将该语句移动到大概没有任何意义的范围内。使用移动线(Alt+Shift+Up)再次实行此操作,并再次观察其举动。

图 3-20。
Move Statement and Move Line
让我们实行另一个例子,通过将你的构造函数移到类的底部来展示 Move 语句的强大功能。确保在Sandbox()声明和它上面的注释块之间没有空行。现在,将光标放在Sandbox()的声明行上的任意位置,通过按住 Ctrl|Cmd 和 Shift 键并重复按下向下箭头键来调用 Move Statement Down,直到您的构造函数是类中的最后一个方法。请注意,包括注释在内的整个块都跳到了类的底部,同时避开了其他方法。表 3-5 描述了移动代码操作及其键盘快捷键。
表 3-5。
Move Code Options
| [计]选项 | 电脑钥匙 | Mac 密钥 | 描述 | | --- | --- | --- | --- | | 下移语句 | ctrl+Shift+向下 | Cmd+Shift+Down | 在范围边界内向下移动一条或多条语句。如果移动一个块,整个块将一起跳到下一个语法精确的位置。 | | 将语句上移 | ctrl+Shift+向上 | cmd+Shift+向上 | 与下移语句雷同,但上移。 | | 下移一行 | Alt+Shift+Down | Alt+Shift+Down | 向下移动语句或行。不服从范围边界或语法。 | | 向上移动一行 | Alt+Shift+Up | Alt+Shift+Up | 与下移一行雷同,但上移。 | 设计您的代码

代码风格约定不断发展。对于在方法后面应该放置多少空格,或者左大括号应该出现在方法签名的同一行照旧紧接在方法签名的下面,没有严酷的规则。组织倾向于界说他们自己的代码风格,但是代码风格也因程序员而异;您也大概有一种自己喜欢的代码风格。荣幸的是,Android Studio 使得设计和组织代码变得简单。在开始设计代码样式之前,让我们检查一下代码样式的设置。选择文件➤设置➤码样式,弹出设置对话框,如图 3-21 所示。Java 和 XML 是我们对 Android 最感兴趣的语言。在左窗格中切换打开代码样式,选择 Java,并检查设置窗口中的每个选项卡。

图 3-21。
Settings dialog box with Code Style ➤ Java selected and showing the Wrapping and Braces tab
通过选择/取消选择各个选项卡中心窗格中的复选框来试验这些设置,并注意右窗格中的示例类如何相应地改变以顺应您的风格。单击顶部的“管理”按钮,界说一个新方案。现在点击另存为,给你的方案起个名字,比如 android,然后点击确定。如果您对已生存的方案做了进一步的更改,请单击“应用”按钮来应用这些更改。当您使用 Ctrl+Alt+L | Cmd+Alt+L 设置代码格式时,将应用您在代码样式选项卡中选择的设置。表 3-6 中描述了代码组织选项。
表 3-6。
Code-Organizing Options
| [计]选项 | 电脑钥匙 | Mac 密钥 | 描述 | | --- | --- | --- | --- | | 自动缩进行 | Ctrl+Alt+I | Ctrl+Alt+I | 根据方案设置对当前选定的一行或多行应用缩进。 | | 优化导入 | Ctrl+Alt+O | Ctrl+Alt+O | 从 import 语句中删除任何未使用的导入。Android Studio 非常注意保持导入的干净和相干性,这个命令实际上是多余的。 | | 重新排列代码 | 没有人 |   | 根据排列设置中建立的规则重新排列代码元素的顺序。 | | 重新格式化代码 | Ctrl+Alt+L | Cmd+Alt+L | 为特定方案应用代码样式设置。 | 自动缩进行

自动缩进行对于在编码时保持行的精确缩进很有用。Java 中控制制表符和缩进的规则可以通过文件➤设置➤代码样式➤ Java ➤制表符和缩进来访问。自动缩进行应用于当前行,或者如果您选择了多行,则应用于所有选定的行。
在Sandbox.java中,选择整个方法代码块并按 Tab 键。该块应该向右移动一个制表符的隔断。现在将光标放在该块的第一行,并在 PC 和 Mac 上按 Ctrl+Alt+I。您会注意到,自动缩进会将该行重新定位到适当的缩进位置,尽管方法块的其余部分不受影响。现在,通过按 Ctrl+A | Cmd+A 选择该类中的所有代码,并再次按 Ctrl+Alt+I。这一次,将对整个文件应用适当的缩进。
重新排列代码

排列决定了代码中元素的顺序。例如,大多数人喜欢将类成员声明放在类的顶部,然后是构造函数,最后是 getters 和 setters,等等。您可以通过文件➤设置➤代码风格➤ Java ➤排列访问排列选项卡,编辑排列设置。
在上一节中,您将构造函数移到了类的底部。这通常不属于它的位置。从主菜单中选择代码➤重排代码。你会注意到你的构造函数已经回到了它的预期位置,在声明部分的下面。重排代码根据排列设置中的规则执行此重排操作。
重新格式化代码

重新格式化代码是最强大的代码样式操作,因为它为您提供了应用代码样式设置中界说的所有代码样式选项的选项。正如你已经看到的,代码风格设置可以从主菜单通过文件➤设置➤代码风格。别的,重新格式化代码允许您重新格式化当前选定的文件,或雷同范例和目次的每个文件。别的,重新格式化代码允许你链接重排条目(这将在 Java 文件上应用重排代码),并优化导入到命令中,如图 3-22 所示。实行通过按 Ctrl+Alt+L | Cmd+Alt+L 来重新格式化Sandbox.java。

图 3-22。
Reformat Code dialog box with Rearrange Entries selected
围绕着

Surround With(Ctrl+Alt+T | Cmd+Alt+T)是 Live Template(Ctrl+Alt+J | Cmd+Alt+J)中功能的超集。但是,Surround With 还包括用 Java 块困绕所选语句的选项,例如if/else、for、try/catch等等。虽然你的沙箱类中的简单代码不会威胁抛出任何检查过的异常,但是用try/catch块困绕威胁抛出异常的语句是最好的围绕应用之一;这大概就是为什么快捷键 Ctrl+Alt+T | Cmd+Alt+T 中包罗一个 T 的原因。围绕操作如表 3-7 所示。
表 3-7。
Surround With Options
| [计]选项 | 电脑钥匙 | Mac 密钥 | 描述 | | --- | --- | --- | --- | | 用...困绕 | Ctrl+Alt+T | Cmd+Alt+T | 用 Java 代码块将所选语句括起来,如 if/else、for、try/catch 等。 | | 展开/移除 | Ctrl+Shift+Delete | Cmd+Shift+Delete | 从选定的一条或多条语句中解开代码块。 | 在Sandbox.java的add()方法中,您希望确保没有重复。如图 3-23 所示,用if/else块将返回的mGreetings.add(object);围住。选择整行并按 Ctrl+Alt+T | Cmd+Alt+T 激活围绕。现在从菜单中选择if/else。在if语句的括号中,键入!mGreetings.contains(object)并且在 else 块范例中返回 false。

图 3-23。
Wrapping and unwrapping blocks of code with Surround With
假设您的业务规则已经改变,您不再关心mGreetings中的重复条目。使用展开/移除来移除您刚刚创建的if/else块。将光标放在return mGreetings.add(object);语句的任意位置,按 Ctrl+Shift+Delete | Cmd+Shift+Delete,选择unwrap if。该方法现在看起来应该和您修改它之前一样。
Surround With 的另一个巨大应用是迭代集合。在上一节中,您自动生成了一个toString()方法。现在修改这个方法,以便迭代mGreetings集合。从toString()方法中删除 return 语句,这样toString()方法的主体就是空的。现在键入 mGreetings,然后按 Ctrl+Alt+T | Cmd+Alt+T。从列表中选择Iterate Iterable,或者按 I 键。再次按回车键担当greeting作为单个元素的名称。产生的代码是一个for-each循环。注意,Android Studio 明白mGreetings包罗Strings,并且它还生成了一个名为greeting的局部变量,其单数情势为mGreetings减去m。根据图 3-24 进一步修改add()方法。

图 3-24。
Using Surround With to iterate an iterable
摘要

本章介绍了 Android Studio 最重要的代码生成特性。我们建议您返回文件➤设置➤代码样式➤ Java 和文件➤设置➤代码样式➤,并花几分钟时间探索那边的各种设置。Android Studio 为编码提供了很多键盘快捷键,但你不必全部记着。如果你不知所措,你可以使用这本书作为参考,或导航到代码菜单,并探索其菜单项和子菜单作为参考。
四、重构代码

你在 Android Studio 中开发的解决方案从设计到完成不会总是遵照一条直线。要成为一名高效的 Android 程序员,你需要在开发、调试和测试的过程中保持灵活性并重构代码。在前一章中,你学习了 Android Studio 如何生成代码;在这一章中,你将看到 Android Studio 如何重构你的代码。重构代码的最大风险是你大概会引入意想不到的错误。Android Studio 通太过析某些有风险的重构操作的结果来降低这些风险,然后激活查找工具窗口,在提交之前,您可以在其中预览您的更改(标志有任何错误或辩说)。
本章介绍的许多重构操作也可以在没有 Android Studio 重构工具的环境下执行。然而,您应该避免强力重构(例如,借助全局查找替换选项),因为 Android Studio 并不总是能够避免您在这些环境下引入错误。相比之下,如果 Android Studio 检测到你正在实行重构操作,它会试图阻止你犯任何愚蠢的错误。例如,在“项目工具”窗口中,将 Java 源文件从一个包拖到另一个包将欺压执行重构➤移动操作,该操作分析移动操作的结果,允许您预览更改,然后将整个项目中该类的任何导入语句优雅地更改为新的完全限定包名。
大多数重构操作都局限于一个方法或一个类,因此不太大概在项目中引入错误。有风险的重构操作是那些涉及两个或更多素材的操作。如果重构操作引入了编译错误,检查管理器将在编辑器中用赤色标签标志受影响的素材。此时,您可以实行修复它们,或者通过按 Ctrl+Z | Cmd+Z 来简单地撤消整个重构操作。如果重构操作成功且没有编译错误,但仍然涉及大量素材,您仍然应该运行您的测试来验证您没有引入任何运行时错误。第十一章涵盖了测试。
Tip
您应该将任何重要的重构更改作为单个 Git 提交,以便您可以在以后轻松地规复该提交。第七章涵盖了 Git。
这一章主要关注最有用的重构操作。在我们开始讨论单独的重构操作之前,我们想指出 Android Studio 有一个非常方便的重构操作,叫做重构➤重构这个。选择这个选项会表现一个上下文菜单,如图 4-1 所示,它聚集了最有用的重构操作。这个操作的键盘快捷键是 Ctrl+Alt+Shift+T | Ctrl+T,在 PC 上你可以通过它方便记忆的首字母缩略词:CAST 来记着它。

图 4-1。
The Refactor This menu with the most useful refactoring operations
在开始学习本章中的例子之前,修改第三章中的Sandbox.java文件,使其不扩展任何内容,既不包罗方法也不包罗成员,如下所示:
public class Sandbox {
}
重新命名

从项目工具窗口选择Sandbox,然后导航到重构➤重命名或按 Shift+F6。产生的对话框允许您重命名您的类,并重命名注释、测试用例以及继承的类中出现的该名称。将Sandbox重命名为 Playpen,点击重构按钮,如图 4-2 所示。您应该会在项目中看到重命名操作的结果。现在通过按 Ctrl+Z | Cmd+Z 撤消重命名操作。

图 4-2。
Rename Sandbox to Playpen
更改签名

更改签名操作使您能够更改方法的以下属性:可见性、名称、返回范例、参数和引发的异常。在Sandbox.java中创建一个方法,如下面的代码片断所示:
public String``greetings
return "Hello " + message;
}
将光标放在单词greetings(以粗体突出表现)上的任意位置,然后按 Ctrl+F6 | Cmd+F6,或者导航到重构➤更改签名。出现的对话框允许你修改方法的签名,如图 4-3 所示。

图 4-3。
The Change Signature dialog box
在参数选项卡中,点击String信息项。将String参数的名称从message改为问候语,如图 4-3 所示。绿色加号和赤色减号图标分别允许您向方法中添加参数或从中减去参数;您可以在列表中编辑它们的范例和名称。除了修改当火线法之外,您还可以通过重载方法单选按钮来选择委托。选择这个单选按钮将使您的原始方法不受影响,但是会用您界说的新签名生成另一个方法。在 Java 中,如果一组方法具有雷同的名称,但是参数顺序和/或参数范例差别,则可以认为它们是重载的。但是,我们所做的更改并没有使这个方法适合重载。如果您乐意,可以在提交更改前通过单击预览按钮来预览更改。若要完成操作并关闭对话框,请单击“重构”按钮。
范例迁徙

顾名思义,范例迁徙允许您从一种 Java 范例迁徙到另一种范例。让我们假设您创建了一个Person类。在进一步的开发中,您发现Person过于一般化,因此您创建了一个扩展Person的Manager类。如果您想将Person的所有实例迁徙到Manager,您可以通过范例迁徙轻松完成。
将光标放在greetings方法的String声明上(在下面的代码片断中以粗体突出表现),然后按 Ctrl+Shift+F6 | Cmd+Shift+F6,或者选择“重构➤范例迁徙”。出现的对话框如图 4-4 所示。

图 4-4。
Type migration from string to date
public String greetings(``String
return "Hello " + greet;
}
将java.lang.String改为 java.util.Date,如图 4-4 所示。从选择范围下拉列表中选择打开文件。与大多数重构操作一样,您可以通过单击预览按钮来预览您的更改。单击重构按钮。
移动

您可以通过以下三种方式之一移动源文件:


  • 通过在项目工具窗口中将源文件从一个包拖到另一个包
  • 通过选择源文件并从主菜单导航到重构➤移动
  • 通过在项目工具窗口中选择文件并按下 F6
右键单击(在 Mac 上按住 Ctrl 键单击)这个com.apress.gerber.helloworld包,然后选择“新建➤包”。将包命名为 refactor。从项目工具窗口中,将Sandbox类拖放到refactor包中,当出现如图 4-5 所示的对话框时,点击 OK。您在“项目工具”窗口中执行的任何拖放操作都会自动欺压执行重构➤移动操作,这允许您将类从一个包安全地移动到另一个包。

图 4-5。
The Move dialog box, resulting from drag-and-drop
除了移动类,您还可以移动成员。在您的Sandbox类中,界说一个新成员,如下所示:
public static final String HELLO = "Hello Android Studio";
将光标放在这行代码上,然后按 F6。出现的对话框允许你将成员从一个类移动到另一个类,如图 4-6 所示。单击“取消”按钮取消此操作。

图 4-6。
The Move Members dialog box
复制

“复制”与“移动”类似,可通过按键盘快捷键 F5 或从主菜单中选择“重构➤复制”来访问。在项目工具窗口中,选择refactor包中的Sandbox类,然后按 F5。在目标包下拉菜单中选择com.apress.gerber.helloworld包,点击确定,如图 4-7 所示。像我们在这里所做的那样不加选择地复制 Java 源文件并不是一个好主意,因为解析是不明确的,因此容易产生潜伏的错误。

图 4-7。
The Copy Class dialog box
安全删除

让我们删除我们创建的复制类。您可以在 Android Studio 中删除文件和资源,方法是在项目工具窗口中选择它们,然后按下 delete 键。点击refactor包中的Sandbox文件,按 Delete 键。出现的对话框允许您通过选中安全删除复选框来使用安全删除选项。使用安全删除的好处是,我们可以在执行删除之前搜索素材上任何大概被粉碎的依赖关系,如图 4-8 所示。如果在您的项目中发现此素材的任何依赖项,您将可以选择查看它们,或者通过单击“仍然删除”来欺压执行删除操作。

图 4-8。
The Safe Delete dialog box
提取

提取不只是一个操作,而是几个操作。本节涵盖了一些更重要的提取操作:提取变量、提取常数、提取字段、提取参数和提取方法。在Sandbox类中,让我们删除所有成员和方法,从头开始:
public class Sandbox {
}
提取变量

在您的Sandbox.java类中,界说一个方法,如下所示:
private String saySomething(){
return "``Something
}
将光标放在硬编码的Something值(以粗体突出表现)上的任意位置,并选择重构➤提取➤变量,或者按 Ctrl+Alt+V | Cmd+Alt+V,然后在不选中声明最终值复选框的环境下按 Enter。Android Studio 提取一个局部变量,按照硬编码的String命名。您应该会得到这样的结果:
private String saySomething(){
String something = "Something";
return something;
}
提取常数

当你在 Android 中开发应用时,你会发现自己使用了大量的Strings作为键——例如,在Maps和Bundles中。以是提取常量会节省你很多时间。
界说一个方法,如下面的代码片断所示。将光标放在name_key字符串上的任意位置,然后按 Ctrl+Alt+C | Cmd+Alt+C。出现的对话框应该如图 4-9 所示。在这里,Android Studio 为名字提供了几个建议。按照惯例,Java 中的常量都是大写的。选择NAME_KEY并按下回车键。

图 4-9。
Extract Constant NAME_KEY Note
您将需要import android.os.Bundle来创建没有编译时错误的 proceding 方法。
private void addName(String name, Bundle bundle ){
bundle.putString("``name_key
}
您最终应该得到一个名为NAME_KEY的常数,它应该这样界说:
public static final String NAME_KEY = "name_key";
提取字段

提取字段将局部变量转换为类的字段(也称为成员)。
Note
为了创建没有编译时错误的 proceding 方法,您需要导入java.util.Date。
在您的Sandbox类中界说一个方法:
private Date getDate(){
return new``Date
}
将光标放在Date(粗体突出表现)的任意位置,按 Ctrl+Alt+F | Cmd+Alt+F。您将看到如图 4-10 所示的对话框。在 Android 中,命名约定是在字段(也称为成员)前加一个 m。您还会注意到一个下拉菜单,允许您在当火线法、字段声明或构造函数中初始化字段。选择字段声明并按回车键。

图 4-10。
The Extract Field dialog box
您应该会得到这样的结果:
private final Date mDate = new Date();
...
private Date getDate(){
return mDate;
}
删除final关键字,使声明行看起来像下面的代码片断:
private Date mDate = new Date();
提取参数

Extract Parameter 允许您提取一个变量,并将其作为封闭方法的参数。在您的Sandbox类中界说一个方法:
private void setDate(){
mDate = new``Date()
}
将光标放在Date()上的任意位置(以粗体突出表现),按 Ctrl+Alt+P | Cmd+Alt+P,然后按 Enter。结果方法应该类似于下面的代码片断:
private void setDate(Date date){
mDate = date;
}
提取方法

“提取方法”允许您选择一行或多行一连的代码,并将它们放在单独的方法中。你想这么做有两个原因。第一个原因是你有一个太复杂的方法。将一个算法分成大约 10-20 行的离散块,比一个有 100 行代码的方法更容易阅读,也更不容易出错。
重复代码块几乎从来都不是一个好主意,以是如果您发现重复的代码块,最好提取一个方法并调用该方法来代替重复的代码块。通过提取一个方法并在您之前使用重复代码块的地方调用它,您可以在一个地方维护您的方法,并且如果您需要修改它,您只需要修改它一次。在你的Sandbox类中重新创建以下两个方法,如清单 4-1 所示。随意复制粘贴。
Listing 4-1. Exract Method Code
private String methodHello (){
String greet = "Hello";
StringBuilder stringBuilder = new StringBuilder();
for(int nC = 0; nC < 10; nC++){
stringBuilder.append(greet + nC);
}
return  stringBuilder.toString();
}
private String methodGoodbye (){
String greet = "Goodbye";
StringBuilder stringBuilder = new StringBuilder();
for(int nC = 0; nC < 10; nC++){
stringBuilder.append(greet + nC);
}
return stringBuilder.toString();
}
正如我们已经提到的,任何时候你发现自己重复代码块或者复制粘贴代码块,你应该考虑使用 Extract 方法。选择清单 4-1 中所有粗体突出表现的行。现在按 Ctrl+Alt+M | Cmd+Alt+M 提取方法。您将看到一个表现方法签名的对话框。将该方法重命名为 getGreet,如图 4-11 所示,点击确定。

图 4-11。
The Extract Method dialog box
Android Studio 扫描您的文件,发现您有另一个完全雷同的代码块实例。点击【是】担当流程复制对话框中的建议,如图 4-12 所示。

图 4-12。
The Process Duplicates dialog box
您应该得到类似清单 4-2 的结果。结果方法更容易维护,因为它生存在一个地方。
Listing 4-2. Code Resulting from Extract Method Operation
private String methodHello (){
String greet = "Hello";
return  getGreet(greet);
}
private String methodGoodbye (){
String greet = "Goodbye";
return  getGreet(greet);
}
private String getGreet (String greet){
StringBuilder stringBuilder = new StringBuilder();
for(int nC = 0; nC < 10; nC++){
stringBuilder.append(greet + nC);
}
return  stringBuilder.toString();
}
高级重构

本章剩余部分介绍的重构操作是高级的。如果你只是对快速使用 Android Studio 感兴趣,你已经有足够的知识来有效地使用重构操作,你可以跳过这一节。然而,如果你很好地明白了 Java,并且想要深入一些更高级的重构操作,请继承阅读。
通过删除Sandbox.java中的所有方法和成员,从头开始:
public class Sandbox {
}
在项目工具窗口中右键单击(在 Mac 上按住 Ctrl 键单击)该com.apress.gerber.helloworld包,然后选择“新建➤ Java 类”。把你的班级命名为迷你箱。更改Minibox的界说,使其继承自Sandbox,并拥有一个名为mShovel的成员,如下所示:
public class Minibox extends Sandbox {
private String mShovel;
}
向下推动构件,向上拉动构件

向下推成员和向上拉成员与继承一起使用。注意,我们已经在Minibox类中界说了mShovel成员。假设我们厥后决定mShovel大概对其他扩展Sandbox的类有用。为此,打开Minibox类并选择 Refactor ➤向上拉成员。出现的对话框如图 4-13 所示。

图 4-13。
The Pull Members Up dialog box
由于Sandbox是Minibox的超类,默认环境下mShovel成员被选中,下拉成员组合框被设置为com.apress.gerber.helloworld.Sandbox类。单击重构。如果您现在检查Sandbox和Minibox,您会注意到mShovel成员属于Sandbox,不再出现在Minibox中。一般来说,如果您认为某个成员大概对其他扩展类有用,您应该将这些成员提升到层次布局中。要向下推动成员,可以遵照类似的步骤。
用委派替换继承

右键单击(在 Mac 上按住 Ctrl 键单击)这个com.apress.gerber.helloword包,然后选择“新建➤ Java 类”。将您的类命名为 Patio,并将其扩展为Sandbox:
public class Patio extends Sandbox {
}
颠末进一步分析,我们决定Patio不是一个Sandbox,而是有一个Sandbox。要更改这种关系,导航到重构➤用委托替换继承。在弹出的对话框中,点击为委托组件生成 Getter 复选框,如图 4-14 所示。

图 4-14。
The Replace Inheritance with Delegation dialog box
您的Patio类现在应该有一个Sandbox成员,如下面的代码片断所示:
public class Patio {
private final Sandbox mSandbox = new Sandbox();
public Sandbox getSandbox() {
return mSandbox;
}
}
封装字段

封装是一种面向对象的计谋,它通过将类成员的访问级别设为私有来隐蔽类成员,然后通过公共 getter/setter 方法向这些成员提供公共接口。重构➤封装字段类似于代码➤生成➤ Getter 和 Setter,尽管当您选择重构➤封装字段时有更多的选择。打开您的Sandbox类并界说一个名为mChildren的新成员,在下一段代码中以粗体突出表现。从主菜单中,选择重构➤封装字段。
public class Sandbox {
private String mShovel;
private int mChildren;
}
出现的对话框允许您精确选择字段的封装方式以及它们应该具有的访问级别。一个真正封装的字段将具有公共访问器(getter)和赋值器(setter)方法的私有可见性。点击 Refactor 按钮,如图 4-15 所示,注意 Android Studio 已经在我们的Sandbox.java类中为我们生成了 getters 和 setters。

图 4-15。
The Encapsulate Fields dialog box
包装方法返回值

当您需要返回一个对象而不是一个原语时,包装一个返回值大概是有用的(尽管在其他环境下您大概希望包装一个返回值)。将光标放在getChildren()方法上,导航到重构➤包装方法返回值。选中使用现有类复选框,键入 java.lang.Integer 作为名称,键入 value 作为包装字段,如图 4-16 所示。现在单击 Refactor,注意您的getChildren()方法返回了一个Integer对象,而不是一个原语int。

图 4-16。
The Wrap Return Value dialog box
用工厂方法替换构造函数

将光标放在Sandbox类界说的括号内。按 Alt+Insert | Cmd+N 并选择构造函数以生成新的构造函数。选择两个成员,如图 4-17 所示,点击确定。

图 4-17。
The Choose Fields to Initialize by Constructor dialog box
将光标放在新界说的构造函数中的任意位置,如下面的代码片断所示,然后导航到重构➤用工厂方法替换构造函数。出现的对话框如图 4-18 所示。单击“重构”以生成工厂方法。

图 4-18。
The Replace Constructor with Factory Method dialog box
public Sandbox(String shovel, int children) {
mShovel = shovel;
mChildren = children;
}
注意,构造函数现在是私有的,一个新的静态方法返回了一个Sandbox类的实例,如下面的代码片断所示。如果您正在创建单例,此操作特别有用。
public static Sandbox createSandbox(String shovel, int children) {
return new Sandbox(shovel, children);
}
将匿名转换为内部

在Sandbox类的构造函数中,添加下面一行:
new Thread(new Runnable()).start();
将光标放在Runnable()上,按 Alt+Enter 调用代码完成操作。然后选择实现方法。选择run方法并点击确定。您的代码应该类似于下面的代码片断:
new Thread(new Runnable() {
@Override
public void run() {
//do something
}
}).start();
将光标放在Runnable()上,导航到重构➤将匿名转换为内部。Android Studio 给你建议MyRunnable作为类名,如图 4-19 。取消选中“使类成为静态”复选框,然后单击“确定”。注意,现在在Sandbox.java中有了一个名为MyRunnable的私有内部类,它实现了Runnable接口。这个例子没做多少;但是,在委派Views的举动时,您大概有机会使用此操作。

图 4-19。
The Convert Anonymous to Inner dialog box
摘要

本章讨论了 Android Studio 中许多可用的重构操作。重构代码是任何编程项目标须要组成部分,Android Studio 中的重构工具就是其中的佼佼者。Android Studio 通太过析结果来降低执行某些重构操作的风险,并允许您在提交操作之前在 Find tool 窗口中预览结果。最重要的重构操作可从“重构➤重构此对话框”中获得,该对话框通过使用键盘快捷键 Ctrl+Alt+Shift+T | Ctrl+T 来调用
五、提醒 Lab:第一部分

到目前为止,您已经熟悉了创建新项目、编程和重构的基础知识。是时候创建一个 Android 应用了,也就是所谓的 app。本章介绍四个实行项目中的第一个。这些实行旨在让您熟悉在开发应用的背景下使用 Android Studio。在这个项目中,您将开发一个应用来管理您想要记着的项目列表。焦点功能将允许您创建和删除提醒,并将某些提醒标志为重要。提醒文本左侧的橙色标签会强调一个重要项目。该应用将包罗一个动作栏菜单,上下文菜单,一个持久化的当地数据库,以及支持多重选择的设备上的多重选择。
图 5-1 展示了在仿真器上运行的完整应用。这个例子向您介绍了 Android 的基础知识,您还将学习如何通过使用内置的 SQLite 数据库来持久化数据。如果有些题目不熟悉也不用担心;后面的章节将更具体地介绍这些主题。

图 5-1。
The completed app interface Note
我们约请您使用 Git 克隆这个项目,以便跟进,尽管您将从头开始使用它自己的 Git 库重新创建这个项目。如果你的电脑上没有安装 Git,参见第七章。在 Windows 中打开一个 Git-bash 会话(或者在 Mac 或 Linux 中打开一个终端)并导航到C:\androidBook\reference\(如果您没有参考目次,请创建一个。在 Mac 上,导航到/your-labs-parent-dir/reference/)并发出以下 git 命令:git clone https://bitbucket.org/csgerber/reminders.git Reminders。
要操作提醒应用,您可以使用操作栏的溢出菜单。点击溢出按钮,它看起来像菜单栏右侧的三个垂直点,打开一个有两个选项的菜单,如图 5-2 所示:新提醒和退出。点击新建提醒打开如图 5-3 所示的对话框。在对话框中,您可以为新提醒添加文本,然后点击提交将其添加到列表中。轻按“退出”即可退出应用。

图 5-3。
New Reminder dialog box

图 5-2。
App interface with overflow menu activated
点击列表中的任一提醒会打开一个带有两个选项的上下文菜单,如图 5-4 所示:编辑提醒和删除提醒。点击上下文菜单中的编辑提醒打开编辑提醒弹出对话框,如图 5-5 所示,在此可以更改提醒的文本。点击上下文菜单中的删除提醒可从列表中删除提醒。

图 5-5。
Edit Reminder dialog box

图 5-4。
Context menu
开始一个新项目

按照第一章中的说明,使用新建项目领导在 Android Studio 中启动一个新项目。输入提醒作为应用名称,设置公司域为 gerber.apress.com ,选择空白活动模板。将该项目生存在路径C:\androidBook\Reminders下。为了与我们的示例保持一致,最好将您的所有 Lab 项目生存在一个公共文件夹中,例如C:\androidBook(或者对于 Mac/Linux 使用∼/androidBook)。在领导的下一页,选择 Phone and Tablet,将最低 SDK 设置为 API 8: Android 2.2 (Froyo)。通过将你的最小 API 级别设置为 8,你的应用可以被凌驾 99%的 Android 市场使用。单击 Next 按钮,从可用模板中选择空白活动,然后再次单击 Next。将活动名称设置为RemindersActivity,然后点击完成,如图 5-6 所示。

图 5-6。
Entering an activity name
Android Studio 在设计模式下表现activity_reminders.xml。activity_reminders.xml文件是你的主活动的布局,如图 5-7 所示。正如在第一章中所讨论的,项目应该在模拟器或者设备上运行。请随意连接您的设备或启动您的仿真器,并运行该项目进行测试。

图 5-7。
Design mode for activity_reminders
初始化 Git 储存库

创建新项目后的第一步应该是使用版本控制来管理源代码。这本书的所有实行都使用 Git,这是一个流行的版本控制系统,可以与 Android Studio 无缝协作,并且可以在网上免费获得。第七章更彻底地探讨了 Git 和版本控制。
如果您的盘算机上尚未安装 Git,请参考第七章中标题为安装 Git 的章节。从主菜单中选择 VCS ➤导入到版本控制➤创建 Git 存储库。(在 Apple OS 中,选择 VCS ➤ VCS Operations ➤创建 Git 存储库。)图 5-8 和 5-9 展示了这一流程。

图 5-9。
Selecting the root directory for the Git repository

图 5-8。
Creating the Git repository
当提示为 Git init 选择目次时,确保 Git 项目将在根项目目次中初始化(在本例中也称为Reminders)。单击确定。
您会注意到位于项目工具窗口中的大多数文件都变成了棕色,这意味着它们正在被 Git 跟踪,但是还没有被添加到 Git 存储库中,也没有被计划添加。一旦你的项目在 Git 的控制之下,Android Studio 就使用一种颜色方案来指示文件在创建、修改或删除时的状态。随着我们的进展,我们会更具体地解释这个着色方案,不外你可以在这里更具体地研究这个主题:jetbrains.com/idea/help/file-status-highlights.html.
单击位于底部空白处的“更改工具”按钮,切换打开“更改工具”窗口,并展开标志为“未版本化的文件”的叶。这将表现所有被跟踪的文件。要添加它们,请选择未版本化文件叶,然后按 Ctrl+Alt+A | Cmd+Alt+A,或者右键单击未版本化文件叶,然后选择“Git ➤添加”。棕色文件应该已经变成绿色,这意味着它们已经在 Git 中暂存,现在可以提交了。
按 Ctrl+K | Cmd+K 调用提交更改对话框。提交文件是将项目变更记载到 Git 版本控制系统的过程。如图 5-10 所示,作者下拉菜单用于覆盖当前默认提交者。您应该将 Author 字段留空,Android Studio 将简单地使用您在 Git 安装期间最初设置的默认值。取消选择“提交前”部分中的所有复选框选项。将以下消息放入提交消息字段:使用新建项目领导进行初始提交。单击提交按钮,并从下拉项目中再次选择提交。

图 5-10。
Committing changes to Git
默认环境下,项目工具窗口应处于打开状态。“项目工具”窗口以差别的方式组织您的项目,这取决于在窗口顶部的“模式”下拉菜单中选择的视图。默认环境下,下拉菜单设置为 Android view,它根据文件的用途来组织文件,与文件在盘算机操作系统上的组织方式无关。在浏览项目工具窗口时,您会注意到 app 文件夹下有三个文件夹:manifests、java和res。在manifests文件夹中可以找到您的 Android 清单文件。在java文件夹中可以找到你的 Java 源文件。res文件夹生存了你所有的 Android 资源文件。位于res目次下的资源大概是 XML 文件、图像、声音和其他有助于界说应用外观和 UI 体验的资源。一旦你有机会探索 Android 视图,我们建议切换到更直观的项目视图,因为它直接映射到您盘算机上的文件布局。
Note
如果您使用过其他 ide 或旧的 Android Studio 测试版本,您会注意到自从 Android Studio 发布以来,在项目工具窗口中引入了 Android 和包视图。
构建用户界面

默认环境下,Android Studio 在编辑器的新选项卡中打开与主活动相干联的 XML 布局文件,并将其模式设置为 Design,因此可视化设计器通常是您在新项目中看到的第一个东西。可视化设计器允许您编辑应用的可视化布局。屏幕中心是预览窗格。预览窗格表现 Android 设备的可视化表示,同时出现您当前编辑的布局的结果。这种表示可以通过使用屏幕顶部的预览布局控件来控制。这些控件可以调整预览,并可用于选择差别(或多种)风格的 Android 设备,从智能手机到平板电脑或可穿着设备。您还可以更改与布局描述相干联的主题。在屏幕的左侧,您会发现控制面板。它包罗各种控件和小部件,可以拖放到舞台上,舞台是设备的可视化表示。ide 的右侧包罗一个组件树,表现布局中描述的组件的层次布局。布局使用 XML。当您在可视设计器中进行更改时,这些更改会在 XML 中更新。您可以单击“设计”和“文本”选项卡,在可视和文本编辑模式之间切换。图 5-11 指出了视觉设计者的几个关键领域。

图 5-11。
The Visual Designer layout
使用可视化设计器

让我们从创建一个提醒列表开始。单击舞台上的 Hello World TextView控件,然后按 Delete 键删除它。在调色板中找到ListView控件,并将其拖到舞台上。拖动时,IDE 将表现各种度量和对齐参考线,以资助您定位控件,当您拖动控件靠近边缘时,这些参考线每每会与边缘对齐。放下ListView,使其与屏幕顶部对齐。您可以将它放置在左上角或中上方。定位后,在编辑器的右下方找到 Properties 视图。将id属性设置为reminders_list_view。id属性是一个可以赋予控件的名称,允许您在 Java 代码中以编程方式引用它们;这就是我们以后修改 Java 源代码时引用ListView的方式。在属性窗口中更改layout:width属性,并将其设置为match_parent。这将扩展控件,使其占据与其所在的父控件一样多的空间。你将在第八章中了解更多关于设计布局的细节。现在,你的布局应该如图 5-12 所示。

图 5-12。
The activity_reminders layout with a ListView
在 Android 中,一个活动界说了控制用户与应用交互的逻辑。当第一次学习 Android 时,将一个活动想象成应用中的一个屏幕会有所资助,尽管活动大概比这更复杂。这些活动通常会扩大一个布局,该布局界说了事物在屏幕上出现的位置。布局文件被界说为 XML,但可以使用可视化设计器进行可视化编辑,如前所述。
编辑布局的原始 XML

单击底部的文本选项卡,从可视编辑切换到文本编辑。这将表现布局的原始 XML 视图,以及右侧的实时预览。对 XML 所做的更改会立即反映在预览窗格中。通过在表现android:layout_height="match_parent"的行下面插入android:background="#181818",将相对布局的背景颜色更改为深灰色。颜色以十六进制值表示。关于十六进制颜色值的更多信息,参见第九章。请注意,现在有一个深灰色样本出现在您插入的设置根视图组背景颜色的行旁边的 gutter 中。如果您切换回设计模式,您会发现整个布局现在是深灰色的。
直接在 XML 布局文件中硬编码颜色值不是最好的方法。更好的选择是在 values resource 文件夹下界说一个colors.xml文件,并在那边界说您的颜色。我们将值外部化到 XML 文件(如 colors.xml)的原因是,这些资源生存在一个地方并可以在一个地方编辑,在整个项目中可以很容易地引用它们。
选择十六进制值#181818并使用 Ctrl+X | Cmd+X 或选择编辑➤剪切将其剪切到剪贴板。在其位置键入@color/dark_grey。这个值使用特别的语法来引用名为dark_grey的 Android 颜色值。这个值应该在一个名为colors.xml的 Android 资源文件中界说,但是因为这个文件在你的项目中还不存在,Android Studio 用赤色突出表现了这个错误。按 Alt+Enter,系统会提示您改正错误的选项。选择第二个选项,创建颜色值资源dark_grey,然后将该值粘贴到出现的下一个对话框的资源值:字段中,并单击确定。
新的颜色值资源对话框将创建 Android 资源文件colors.xml并用十六进制值添补它。单击“确定”,然后在“将文件添加到 Git”对话框中单击“确定”,将此新文件添加到版本控制中,并确保选中“记着,不要再询问”复选框,这样您就不会再受到此消息的困扰。图 5-13 展示了这一流程。

图 5-13。
Extracting the hard-coded color value as a resource value
预览模式中的ListView包罗的行布局与我们选择的背景颜色没有足够的对比度。要更改这些项目标表现方式,您需要在单独的布局文件中为该行界说一个布局。右键单击res文件夹下的layout文件夹,选择新建➤布局资源文件。在“新建资源文件”对话框中输入 reminders_row。使用LinearLayout作为根视图组,保留其余的默认设置,如图 5-14 所示。

图 5-14。
New Resource File dialog box
现在,您将为单个列表项行创建布局。LinearLayout根视图组是布局中最表面的元素。使用预览窗格顶部工具栏中的控件将其方向设置为vertical。使用此控件时要小心,因为水平线表示垂直方向,反之亦然。图 5-15 突出表现了改变方向按钮。

图 5-15。
Change Orientation button
在预览窗格的右下角找到属性视图。找到layout:height属性并将其设置为50dp。此属性控制控件的高度,dp 后缀是指与密度无关的像素度量。这是 Android 使用的一个指标,允许布局适当缩放,而不管出现它们的屏幕密度如何。您可以单击此视图中的任何属性,并开始键入内容以增量方式搜索属性,然后按向上或向下箭头继承搜索。
将一个水平LinearLayout拖放到垂直LinearLayout内。将一个CustomView控件拖放到水平LinearLayout中,并将其 class 属性设置为android.view.View,以创建一个通用的空视图,并赋予它一个row_tab的id属性。在撰写本文时,Android Studio 中有一个限制,不允许您从面板中拖动通用视图。一旦你点击CustomView,你会得到一个有差别选项的对话框,没有一个选项包罗通用视图类。从对话框中选择任意一个类,并将其放置在布局中。使用 properties 窗格右侧的 properties 窗口找到刚才放置的视图的 class 属性,并将其更改为android.view.View以解决此限制。参考清单 5-1 来查看这是如何完成的。
您将使用此通用视图选项卡将某些提醒标志为重要。在编辑模式仍然设置为文本的环境下,将自界说视图的layout:width属性更改为10dp,将其layout:height属性设置为match_parent。在这里使用match_parent值将使这个View控件与其父容器一样高。切换到设计模式,在组件树的水平LinearLayout中拖放一个Large Text控件,并将其width和height属性设置为match_parent。验证大文本组件是否位于自界说视图控件的右侧。在组件树中,标志为 textView 的组件应该嵌套在 LinearLayout (horizontal)组件中,并位于 View 组件之下。如果“文本视图”出现在“视图”上方,请用鼠标向下拖动它,使它吸附到第二个(也是最后一个)位置。给你的 TextView 控件一个id值row_text,并将其textSize属性设置为18sp。sp 后缀指的是与比例无关的像素测量,其表现类似于dp,但也尊重用户的文本大小设置,例如,如果用户视力不好,并希望其手机上的文本表现较大,sp会尊重此设置,而dp则不会。因此,对textSize使用sp总是一个好主意。你将在第八章中了解更多关于屏幕尺寸的信息。
最后,将 TextView 控件的text属性设置为Reminder Text。切换到文本模式,对 XML 进行额外的修改,使您的代码类似于清单 5-1 。
Listing 5-1. The reminders_row Layout XML Code
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="``http://schemas.android.com/apk/res/android
android:layout_width="match_parent"
android:layout_height="50dp"
androidrientation="vertical">
<LinearLayout
androidrientation="horizontal"
android:layout_width="match_parent"
android:layout_height="48dp">
<view
android:layout_width="10dp"
android:layout_height="match_parent"
class="android.view.View"
android:id="@+id/row_tab" />
<TextView
android:layout_width="match_parent"
android:layout_height="50dp"
android:textAppearance="?
android:attr/textAppearanceLarge"
android:text="Reminder Text"
android:id="@+id/row_text"
android:textSize="18sp" />
</LinearLayout>
</LinearLayout>
现在,您将创建一些自界说颜色。切换到设计模式。在组件树中选择根 LinearLayout (vertical)。将其 android:background 属性设置为@color/dark_grey以重用我们之前界说的颜色。在组件树中选择 row_tab 组件,并将其android:background属性设置为@color/green。选择 row_text 组件,并将其android:textColor属性设置为@color/white。与之前一样,这些颜色没有在colors.xml文件中界说,您需要使用与之前雷同的过程来界说它们。切换到文本模式。重复按 F2 键在这两个附加错误之间来回跳转,然后按 Alt+Enter 键调出 IntelliSense 建议。在两种环境下选择第二个建议,并在弹出的对话框中填入值#ffffff以固定白色,填入值#003300以固定绿色。在使用建议对话框修复这些错误后,您可以按住 Ctrl 键并左键单击这些颜色中的任何一种,这将把您带到colors.xml文件,看起来应该如清单 5-2 所示。
Listing 5-2. The colors.xml File
<resources>
<color name="dark_grey">#181818</color>
<color name="white">#ffffff</color>
<color name="green">#003300</color>
</resources>
返回到activity_reminders.xml布局文件。现在你可以将新的reminders_row布局连接到这个布局中的ListView。切换到文本模式,给ListView元素添加如下属性:tools:listitem="@layout/reminders_row",如图 5-16 所示。

图 5-16。
The preview pane is now rendering a custom ListView layout
添加此属性不会更改布局运行时的出现方式;它只是改变了预览窗格对列表视图中每个项目标使用。要使用新的布局,您必须使用 Java 代码来扩展它,我们将在后续步骤中向您展示如何操作。
添加视觉增强

您已经完成了 ListView 行的自界说布局,但是您不应该就此止步。添加一些视觉增强会让你的应用与众差别。看看文本是如何在屏幕上出现的。仔细的人会发现它稍微偏离了中心,碰到了左边的绿色标签。打开reminders_row布局进行一些小的调整。您希望文本向行的垂直中心移动,并提供一些添补,以便从侧边提供一些视觉分离。用清单 5-3 中的代码替换您的TextView元素。
Listing 5-3. TextView Additional Attributes
<TextView
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="Reminder Text"
android:id="@+id/row_text"
android:textColor="@color/white"
android:textSize="18sp"
android:gravity="center_vertical"
android:padding="10dp"
android:ellipsize="end"
android:maxLines="1"
/>
附加的ellipsize属性将截断太长的文本,使其不适合末端带有省略号的行,而maxLines属性将每行的行数限制为 1。最后,从清单 5-4 中添加两个通用视图对象,在内部LinearLayout之后,外部LinearLayout的结束标志之前,在该行下面创建一个水平标尺。外LinearLayout设置为高度50dp,内LinearLayout设置为高度48dp。两个通用视图对象将占据布局内剩余的垂直 2dp,从而创建一个斜边。这表现在清单 5-4 中。
Listing 5-4. Extra Generic Views for beveled edge
</LinearLayout>
<view
class="android.view.View"
android:layout_width="fill_parent"
android:layout_height="1dp"
android:background="#000"/>
<view
class="android.view.View"
android:layout_width="fill_parent"
android:layout_height="1dp"
android:background="#333"/>
</LinearLayout>
向 ListView 添加项目

现在,您将对使用您刚刚修改的布局的活动进行更改。打开项目工具窗口,在您的java源文件夹下找到RemindersActivity文件。它将位于com.apress.gerber.reminders包下。在这个文件中找到onCreate()方法。它应该是您的类中界说的第一个方法。声明一个名为 mListView 的 ListView 成员,并将onCreate()方法修改成清单 5-5 中的代码。您将需要解析导入 ListView 和 ArrayAdapter。
Listing 5-5. Add List Items to the ListView
public class RemindersActivity extends ActionBarActivity {
private ListView mListView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_reminders);
mListView = (ListView) findViewById(R.id.reminders_list_view);
//The arrayAdatper is the controller in our
//model-view-controller relationship. (controller)
ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(
//context
this,
//layout (view)
R.layout.reminders_row,
//row (view)
R.id.row_text,
//data (model) with bogus data to test our listview
new String[]{"first record", "second record", "third record"});
mListView.setAdapter(arrayAdapter);
}
//Remainder of the class listing omitted for brevity
}
这段代码通过使用您之前界说的id属性来查找ListView,并删除默认的列表分隔线,以便我们之前创建的定制斜面分隔线能够精确出现。该代码还创建了一个带有几个示例列表项的适配器。Adapter是一个特别的 Java 类,被界说为 Android SDK 的一部分,在 SQLite 数据库(模型)、ListView(视图)和适配器(控制器)之间的模型-视图-控制器关系中充当控制器。适配器将模型绑定到视图,并处理更新和刷新。Adapter 是 ArrayAdapter 的超类,它将数组的元素绑定到视图。在我们的例子中,这个视图是一个 ListView。ArrayAdapter在其三参数构造函数中担当三个参数。第一个参数是由当前活动表示的一个Context对象。适配器还需要知道应该使用哪个布局和布局中的哪个或哪些字段来表现行数据。为了满足这个需求,您通报布局和布局中的TextView项的 id。最后一个参数是用于列表中每一项的字符串数组。如果此时运行项目,您将会看到列表视图中表现的ArrayAdapter构造函数中给出的值,如图 5-17 所示。

图 5-17。
ListView example
按 Ctrl+K | Cmd+K 提交对 Git 的更改,并使用带有自界说颜色的 Adds ListView 作为提交消息。当您完成一个项目时,最好对 Git 执行增量提交,同时使用提交消息来描述每次提交添加/删除/更改的特性。保持这种习惯使得识别单个提交和为将来的合作者和用户构建发布说明变得容易。
设置操作栏溢出菜单

Android 使用一种常见的视觉元素,称为动作栏。操作栏是许多应用定位导航和其他允许用户执行重要任务的选项的地方。此时运行应用时,您大概会注意到一个看起来像三个垂直点的菜单图标。这些点被称为溢出菜单。单击溢出菜单图标会产生一个菜单,其中有一个名为settings的菜单项。该菜单项作为新建项目领导模板的一部分放在那边,本质上是一个不执行任何操作的占位符。RemindersActivity加载menu_reminders.xml文件,该文件位于res/menu文件夹下。对这个文件进行修改,向活动添加新的菜单项,如清单 5-6 所示。
Listing 5-6. New Menu Items
<menu xmlns:android="``http://schemas.android.com/apk/res/android
xmlns:app="``http://schemas.android.com/apk/res-auto
xmlns:tools="``http://schemas.android.com/tools
tools:context="com.apress.gerber.reminders.app.RemindersActivity" >
<item android:id="@+id/action_new"
android:title="new Reminder"
androidrderInCategory="100"
app:showAsAction="never" />
<item android:id="@+id/action_exit"
android:title="exit"
androidrderInCategory="200"
app:showAsAction="never" />
</menu>
在前面的代码清单中,title属性对应于菜单项中表现的文本。由于我们已经对这些属性进行了硬编码,Android Studio 会将这些值标志为警告。按 F2 在这些警告之间跳转,按 Alt+Enter 调出 IntelliSense 建议。您只需按 Enter 键担当第一个建议,为新的字符串资源键入一个名称,当对话框弹出时,再次按 Enter 键接奉命名的资源。使用new_reminder作为第一个项目标名称,使用exit作为第二个项目标名称。
打开RemindersActivity并用清单 5-7 中的文本替换onOptionsItemSelected()方法。您需要解决日志类的导入问题。当你点击应用中的一个菜单项时,运行时会调用这个方法,传入一个被点击的MenuItem的引用。switch语句担当MenuItem的itemId,并根据点击的项目执行日志语句或终止活动。这个例子使用了将文本写入 Android 调试日志的Log.d()方法。如果您的应用包罗多个活动,并且这些活动是在当前活动之前查看的,那么调用finish()将简单地从 backstack 中弹出当前活动,控制权将通报给下一个底层活动。因为 RemindersActivity 是这个应用中唯一的活动,finish()方法从 backstack 中弹出唯一的活动,并导致您的应用终止。
Listing 5-7. onOptionsItemSelected( ) Method Definition
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_new:
//create new Reminder
Log.d(getLocalClassName(),"create new Reminder");
return true;
case R.id.action_exit:
finish();
return true;
default:
return false;
}
}
运行应用并测试新的菜单选项。轻按新的提醒菜单选项,并观看 Android 日志以查看消息出现。在仿真器或设备上运行应用时,将会打开 Android DDMS(Dalvik 调试监控服务)窗口,您需要选择日志级别下的调试选项来查看调试日志。运行您的应用并与菜单项交互。点击新的提醒菜单项时,请注意 Android DDMS 窗口中的日志。最后,按 Ctrl+K | Cmd+K,使用添加新的提醒和退出菜单选项作为提交消息,将代码提交给 Git。
连续提醒

因为提醒应用需要维护一个提醒列表,以是你需要一个持久性计谋。Android SDK 和运行时提供了一个名为 SQLite 的嵌入式数据库引擎,该引擎旨在在内存受限的环境中运行,非常适合移动设备。本节介绍 SQLite 数据库,并探讨如何维护提醒列表。我们的计谋将包括一个数据模型、一个数据库代理类和一个CursorAdapter。该模型将生存从数据库读取和写入数据库的数据。代理将是一个适配器类,它将把来自应用的简单调用转换成对 SQLite 数据库的 API 调用。最后,CursorAdapter将扩展一个标准的 Android 类,以抽象的方式处理数据访问。
数据模型

让我们从创建数据模型开始。右键单击 com.apress.gerber.reminders 包并选择 New ➤ Java Class。命名您的课堂提醒,然后按回车键。用清单 5-8 中的代码装饰你的类。这个类是一个简单的 POJO (Plain Old Java Object ),它界说了一些实例变量和相应的 getter 和 setter 方法。Reminder类包括一个整数 ID、一个字符串值和一个数字重要性值。ID 是用于识别每个提醒的唯一号码。字符串值生存提醒的文本。重要性值是一个数字指示器,将单个提醒标志为重要(1 =重要,0 =不重要)。我们在这里使用了int而不是boolean,因为 SQLite 数据库没有boolean数据范例。
Listing 5-8. Reminder Class Definition
public class Reminder {
private int mId;
private String mContent;
private int mImportant;
public Reminder(int id, String content, int important) {
mId = id;
mImportant = important;
mContent = content;
}
public int getId() {
return mId;
}
public void setId(int id) {
mId = id;
}
public int getImportant() {
return mImportant;
}
public void setImportant(int important) {
mImportant = important;
}
public String getContent() {
return mContent;
}
public void setContent(String content) {
mContent = content;
}
}
现在,您将创建一个数据库代理。同样,这个代理将把简单的应用调用转换成较低级别的 SQLite API 调用。在 com.apress.gerber.reminders 包中创建一个名为RemindersDbAdapter的新类。将清单 5-9 中的代码直接放在新创建的 RemindersDbAdapter 类中。当您解析导入时,您会注意到在 Android SDK 中找不到 DatabaseHelper。我们将在后续步骤中界说 DatabaseHelper 类。此代码界说了列名和索引;一个TAG用于测井;两个数据库 API 对象;数据库名称、版本和主表名称的一些常量;上下文对象;和用于创建数据库的 SQL 语句。
Listing 5-9. Code to be placed inside the RemindersDbAdapter class
//these are the column names
public static final String COL_ID = "_id";
public static final String COL_CONTENT = "content";
public static final String COL_IMPORTANT = "important";
//these are the corresponding indices
public static final int INDEX_ID = 0;
public static final int INDEX_CONTENT = INDEX_ID + 1;
public static final int INDEX_IMPORTANT = INDEX_ID + 2;
//used for logging
private static final String TAG = "RemindersDbAdapter";
private DatabaseHelper mDbHelper;
private SQLiteDatabase mDb;
private static final String DATABASE_NAME = "dba_remdrs";
private static final String TABLE_NAME = "tbl_remdrs";
private static final int DATABASE_VERSION = 1;
private final Context mCtx;
//SQL statement used to create the database
private static final String DATABASE_CREATE =
"CREATE TABLE if not exists " + TABLE_NAME + " ( " +
COL_ID + " INTEGER PRIMARY KEY autoincrement, " +
COL_CONTENT + " TEXT, " +
COL_IMPORTANT + " INTEGER );";
SQLite API

DatabaseHelper是一个 SQLite API 类,用于打开和关闭数据库。它使用了Context,这是一个抽象的 Android 类,提供对 Android 操作系统的访问。DatabaseHelper是一个自界说类,必须由你界说。使用清单 5-10 中的代码将DatabaseHelper实现为RemindersDbAdapter的内部类。将此代码放在 RemindersDbAdapters 的末端,但仍在 RemindersDbAdapters 的大括号内。
Listing 5-10. RemindersDbAdapter
private static class DatabaseHelper extends SQLiteOpenHelper {
DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
Log.w(TAG, DATABASE_CREATE);
db.execSQL(DATABASE_CREATE);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
+ newVersion + ", which will destroy all old data");
db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
onCreate(db);
}
}
DatabaseHelper扩展了SQLiteOpenHelper,这有助于用特别的回调方法维护数据库。回调方法是运行时环境将在应用的整个生命周期中调用的方法,它们使用提供的SQLiteDatabase db变量来执行 SQL 命令。构造函数是初始化数据库的地方。构造函数将数据库名称和版本通报给它的超类;然后超类做建立数据库的艰苦工作。当运行时需要创建数据库时,会自动调用onCreate()方法。此操作仅运行一次,即应用初次启动且数据库尚未创建时。每当数据库需要升级时,就会调用onUpgrade()方法,例如,如果开发职员更改了模式。如果您确实更改了数据库模式,请确保将DATABASE_VERSION加 1,然后onUpgrade()将管理剩余的部分。如果你忘记增长DATABASE_VERSION,即使在调试构建模式下,你的程序也会瓦解。在前面的代码中,我们运行一个 SQL 命令来删除数据库中唯一的一个表,然后运行onCreate()方法来重新创建该表。
清单 5-11 中的代码演示了如何使用DatabaseHelper打开和关闭数据库。构造函数生存了一个Context的实例,该实例被通报给DatabaseHelper。open()方法初始化助手并使用它来获取数据库的实例,而close()方法使用助手来关闭数据库。在 RemindersDbAdapter 类中所有成员变量界说之后和DatabaseHelper内部类界说之前添加此代码。当您解析导入时,使用android.database.SQLException类。
Listing 5-11. Database Open and Close Methods
public RemindersDbAdapter(Context ctx) {
this.mCtx = ctx;
}
//open
public void open() throws SQLException {
mDbHelper = new DatabaseHelper(mCtx);
mDb = mDbHelper.getWritableDatabase();
}
//close
public void close() {
if (mDbHelper != null) {
mDbHelper.close();
}
}
清单 5-12 包罗了处理tbl_remdrs表中Reminder对象的创建、读取、更新和删除的所有逻辑。这些通常被称为 CRUD 操作;CRUD 代表创建、读取、更新和删除。在 RemindersDbAdapter 类中的close()方法之后添加下面的代码。
Listing 5-12. Database CRUD Operations
//CREATE
//note that the id will be created for you automatically
public void createReminder(String name, boolean important) {
ContentValues values = new ContentValues();
values.put(COL_CONTENT, name);
values.put(COL_IMPORTANT, important ? 1 : 0);
mDb.insert(TABLE_NAME, null, values);
}
//overloaded to take a reminder
public long createReminder(Reminder reminder) {
ContentValues values = new ContentValues();
values.put(COL_CONTENT, reminder.getContent()); // Contact Name
values.put(COL_IMPORTANT, reminder.getImportant()); // Contact Phone Number
// Inserting Row
return mDb.insert(TABLE_NAME, null, values);
}
//READ
public Reminder fetchReminderById(int id) {
Cursor cursor = mDb.query(TABLE_NAME, new String[]{COL_ID,
COL_CONTENT, COL_IMPORTANT}, COL_ID + "=?",
new String[]{String.valueOf(id)}, null, null, null, null
);
if (cursor != null)
cursor.moveToFirst();
return new Reminder(
cursor.getInt(INDEX_ID),
cursor.getString(INDEX_CONTENT),
cursor.getInt(INDEX_IMPORTANT)
);
}
public Cursor fetchAllReminders() {
Cursor mCursor = mDb.query(TABLE_NAME, new String[]{COL_ID,
COL_CONTENT, COL_IMPORTANT},
null, null, null, null, null
);
if (mCursor != null) {
mCursor.moveToFirst();
}
return mCursor;
}
//UPDATE
public void updateReminder(Reminder reminder) {
ContentValues values = new ContentValues();
values.put(COL_CONTENT, reminder.getContent());
values.put(COL_IMPORTANT, reminder.getImportant());
mDb.update(TABLE_NAME, values,
COL_ID + "=?", new String[]{String.valueOf(reminder.getId())});
}
//DELETE
public void deleteReminderById(int nId) {
mDb.delete(TABLE_NAME, COL_ID + "=?", new String[]{String.valueOf(nId)});
}
public void deleteAllReminders() {
mDb.delete(TABLE_NAME, null, null);
}
这些方法都使用SQLiteDatabase mDb变量来生成和执行 SQL 语句。如果您熟悉 SQL,您大概会猜测这些 SQL 语句将采取INSERT、SELECT、UPDATE或DELETE的情势。
这两个创建方法使用一个特别的ContentValues对象,它是一个数据穿梭器,用于将数据值通报给数据库对象的insert方法。数据库最终会将这些对象转换成 SQL insert语句并执行它们。有两个read方法,一个用于获取单个提醒,另一个用于获取光标来迭代所有提醒。您将在稍后的特别Adapter课程中使用Cursor。
update方法类似于第二个创建方法。然而,这个方法调用了低级数据库对象上的一个update方法,该方法将生成并执行一个update SQL 语句,而不是一个insert。
最后,有两个delete方法。第一个使用一个id参数,并使用数据库对象为特定的提醒生成并执行一个delete语句。第二种方法要求数据库生成并执行一个delete语句,从表中删除所有提醒。
此时,您需要一种方法将提醒从数据库中取出并放入ListView。清单 5-13 展示了通过扩展您之前看到的特别的Adapter Android 类将数据库值绑定到单个行对象的须要逻辑。在 com.apress.gerber.reminders 包中创建一个名为 RemindersSimpleCursorAdapter 的新类,并用下面的代码修饰它。在解析导入时,使用 Android . support . v4 . widget . simplecursoradapter 类。
Listing 5-13. RemindersSimpleCursorAdapter Code
public class RemindersSimpleCursorAdapter extends SimpleCursorAdapter {
public RemindersSimpleCursorAdapter(Context context, int layout, Cursor c, String[] from, int[] to, int flags) {
super(context, layout, c, from, to, flags);
}
//to use a viewholder, you must override the following two methods and define a ViewHolder class
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
return super.newView(context, cursor, parent);
}
@Override
public void bindView(View view, Context context, Cursor cursor) {
super.bindView(view, context, cursor);
ViewHolder holder = (ViewHolder) view.getTag();
if (holder == null) {
holder = new ViewHolder();
holder.colImp = cursor.getColumnIndexOrThrow(RemindersDbAdapter.COL_IMPORTANT);
holder.listTab =  view.findViewById(R.id.row_tab);
view.setTag(holder);
}
if (cursor.getInt(holder.colImp) > 0) {
holder.listTab.setBackgroundColor(context.getResources().getColor(R.color.orange));
} else {
holder.listTab.setBackgroundColor(context.getResources().getColor(R.color.green));
}
}
static class ViewHolder {
//store the column index
int colImp;
//store the view
View listTab;
}
}
我们用ListView注册Adapter来添补提醒。在运行时,当用户加载和滚动列表时,ListView将重复调用Adapter上的bindView()方法和屏幕上的View对象。用列表项添补这些视图是Adapter的工作。在这个代码示例中,我们使用了名为SimpleCursorAdapter的Adapter的子类。这个类使用一个Cursor对象,它跟踪表中的行。
这里你可以看到一个ViewHolder模式的例子。这是一个众所周知的 Android 模式,其中一个小的ViewHolder对象作为标签附加在每个视图上。这个对象通过使用来自数据源的值为列表中的View对象添加装饰,在这个例子中是Cursor。ViewHolder被界说为具有两个实例变量的静态内部类,一个用于重要表列的索引,另一个用于您在布局中界说的row_tab视图。
bindView()方法起首调用超类方法,该方法将光标的值映射到视图中的元素。然后,它检查是否有一个持有者被附加到标签上,如果需要,创建一个新的持有者。然后,bindView()方法通过使用重要的列索引和您之前界说的row_tab来配置 holder 的实例变量。找到或配置持有者后,它使用当前提醒中的COL_IMPORTANT常量的值来决定对row_tab使用哪种颜色。该示例使用了新的橙色,您需要将它添加到您的colors.xml: <color name="orange">#ffff381a</color>中。
之前您使用了一个ArrayAdapter来管理模型和视图之间的关系。SimpleCursorAdapter遵照雷同的模式,尽管它的模型是 SQLite 数据库。对清单 5-14 进行更改,以使用新的 RemindersDbAdapter 和 RemindersSimpleCursorAdapter。
Listing 5-14. RemindersActivity Code
public class RemindersActivity extends ActionBarActivity {
private ListView mListView;
private RemindersDbAdapter mDbAdapter;
private RemindersSimpleCursorAdapter mCursorAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_reminders);
mListView = (ListView) findViewById(R.id.reminders_list_view);
mListView.setDivider(null);
mDbAdapter = new RemindersDbAdapter(this);
mDbAdapter.open();
Cursor cursor = mDbAdapter.fetchAllReminders();
//from columns defined in the db
String[] from = new String[]{
RemindersDbAdapter.COL_CONTENT
};
//to the ids of views in the layout
int[] to = new int[]{
R.id.row_text
};
mCursorAdapter = new RemindersSimpleCursorAdapter(
//context
RemindersActivity.this,
//the layout of the row
R.layout.reminders_row,
//cursor
cursor,
//from columns defined in the db
from,
//to the ids of views in the layout
to,
//flag - not used
0);
//the cursorAdapter (controller) is now updating the listView (view)
//with data from the db (model)
mListView.setAdapter(mCursorAdapter);
}
//Abbreviated for brevity
}
如果此时运行应用,您将不会在列表中看到任何内容;该屏幕将完满是空的,因为您的最后一次更改插入了 SQLite 功能来代替示例数据。按 Ctrl+K | Cmd+K 并提交您的更改,同时表现消息“为提醒添加 SQLite 数据库持久性并为重要提醒添加新颜色”。作为一项挑战,您大概会实行找出如何通过使用新的RemindersDbAdapter来添加示例项。这将在下一章讨论,以是你可以向前看并检查你的工作。
摘要

至此,你有了一个成熟的 Android 应用。在这一章中,你学习了如何建立你的第一个 Android 项目,并使用 Git 控制它的源代码。您还探索了如何在设计和文本模式下编辑 Android 布局。您已经看到了在操作栏中创建溢出菜单的演示。本章最后探讨了ListViews和Adapters,并将数据绑定到内置的 SQLite 数据库。在下一章中,您将通过添加创建和编辑提醒的功能来完善应用。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

干翻全岛蛙蛙

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表