Android编程权威指南(第3版)(txt+pdf+epub+mobi电子书下载)


发布时间:2020-05-24 18:45:27

点击下载

作者:[美] 比尔·菲利普斯 克里斯·斯图尔特 克莉丝汀·马西卡诺(Bill Phillips, Chris Stewart, Kristin Marsicano)

出版社:人民邮电出版社

格式: AZW3, DOCX, EPUB, MOBI, PDF, TXT

Android编程权威指南(第3版)

Android编程权威指南(第3版)试读:

献词

献给我桌上的唱片机。感谢你陪伴我完成本书。我保证,很快你就会有新唱针了。——B.P.

献给我的爸爸David,他教我懂得辛苦工作的意义。献给我的妈妈Lisa,她一直督促我去做正确的事。——C.S.

献给我的爸爸Dave Vadas,他激励并支持我投身计算机行业。献给我的妈妈Joan Vadas,在这么多年的浮浮沉沉里,她总能让我保持乐观。(她会给我支招:心情不好的时候就看集《黄金女郎》吧!)——K.M.

致谢

这是本书第3版。我们常说,当然,也应再三强调:仅凭作者是无法成书的。这背后是团队的力量:合作者、责任编辑和支持者。没有他们,想抓住重点并撰写出这么多的出版素材肯定不可能。● Brian Hardy和Bill很有雄心,他们从无到有,写出了本书第1

版。真了不起。● 感谢我们Android开发团队的同事Andrew Lunsford、Bolot

Kerimbaev、Brian Gardner、David Greenhalgh、Josh Skeen、

Matt Compton、Paul Turner和Rashad Cureton。他们一直用这些

还不够完善的材料教学,并提出了不少宝贵建议,也修改了一些

错误。能和这样有趣、有才的团队一起工作,此生无憾。在Big

Nerd Ranch工作的日子,每一天都是享受。● 特别感谢Andrew。他为本书同步更新了一大批Android

Studio截图。他很细心,不放过任何细节,说话还幽默辛辣,令

人欣赏。● Zack Simon,说起话来轻声细语,是我们Big Nerd Ranch了

不起的天才设计师。他不声不响地更新了附在书后的Android开

发速查表,给了我们一个大大的惊喜。Zack,谢谢你!如果速

查表用着不错,你也去谢谢他吧!● 感谢Kar Loong Wong,他重新设计了crime应用列表屏。只

要他多伸手,本书的应用肯定会越来越好看。● 感谢Mark Dalrymple,他审阅了constraint layout这部分内容,

使之更加准确、完善。凑巧碰到他的话,如果你也在搞

constraint layout,千万记得请他把关,他可是这方面的专家。不

搞也没关系,可以请多才多艺的他扎些气球小动物玩玩。● 感谢Aaron Hillegass。他若不创建Big Nerd Ranch公司,这

一切都无从谈起。● 感谢我们的编辑Elizabeth Holaday。据说,著名的“垮掉的

一代”文学作家William S. Burroughs有时会把自己的作品分成多

个部分,抛向空中,然后以稿件的落地顺序出书。要不是Liz,

在遇到困惑、一时冲动时,相信我们也会这么做。在她的指导下,

我们才能有的放矢,写出清晰、简洁的书稿。● 感谢Ellie Volckhausen为本书设计了封面。● 感谢我们的文字编辑Anna Bentley和审稿编辑Simone

Payment。感谢她俩的打磨完善。● 感谢IntelligentEnglish.com网站的Chris Loper。他设计并制

作了本书的纸质版和电子版。他的DocBook工具简直太好用了。

最后感谢我们的学员。我们之间有个反馈环:我们以本书内容教学,他们不断给予反馈。没有这个反馈环,就没有这本书,即便有,也不会越来越完善。如果说Big Nerd Ranch公司的图书够特别(希望如此),功劳就在于这个反馈环。再次感谢。

如何学习Android开发

学习Android开发,对每个新手都是一个很大的挑战,就好像在异国他乡学会生存一样。即使会说当地的语言,一开始也绝不会有在家的感觉,因为你不能完全理解周围的人所理解的东西。原有的知识储备在新环境下可能完全派不上用场。

Android有自己的语言文化——使用Java语言。但仅掌握Java远远不够,还需要通过学习很多新的理论和技术知识来理清头绪,从而指引你穿越陌生的领域。

该我们登场了。在Big Nerd Ranch,我们认为,要成为Android开发人员,必须做到:● 着手开发一些Android应用;● 彻底理解你的Android应用。

本书将协助你完成以上两件事情。我们已用它成功培训了数千名专业的Android开发人员。本书将指导你完成多个Android应用的开发,并根据需要逐步介绍各种理论概念及技术知识。在学习过程中,如果遇到知识疑难点,请勇敢面对;我们也会尽最大努力抽丝剥茧,让你知其然更知其所以然。

我们的教学方法是:在学习理论的同时,就着手运用它们开发实际的应用,而非先学习一大堆理论,再考虑如何将理论应用于实践。读完本书,你将具备必要的开发经验及知识。以此为起点,深入学习,逐渐成长为一名合格的Android开发者。

阅读前提

使用本书,你需要熟悉Java语言,包括类、对象、接口、监听器、包、内部类、匿名内部类、泛型类等基本概念。

如果不熟悉这些概念,很可能刚翻几页就已无法继续下去。对此,建议先放下本书,找本Java入门书看一看。市面上有很多优秀的Java入门书,你可以基于自己的编程经验及学习风格去挑选。

如果你熟悉面向对象编程,但Java知识忘得差不多了,阅读本书应该不会有太大的问题。对于接口、匿名内部类等重要的Java语言点,我们会提供必要的简短回顾。建议在学习过程中手边备上一本Java参考书,方便查阅。

第3版有哪些新内容

本书第3版介绍了一些新工具:constraint layout(包括其编辑器)和数据绑定(data binding)。新增加了几个章节,内容涉及单元测试、辅助功能(accessibility)、MVVM架构和应用本地化。本书末尾还介绍了Android的新运行时权限系统。此外,我们还进一步扩充了

挑战练习

深入学习

部分的内容,并修订了全书的一些不够完善的部分。

如何使用本书

本书基于Big Nerd Ranch培训机构的5天教学课程编写而成。课程从基础知识讲起,各章节内容以循序渐进的方式编排,建议不要跳读,以免学习效果大打折扣。显然,本书不适合作为参考书。本书旨在帮你跨越学习的初始障碍,进而充分利用其他各种参考资料和代码实例类图书来深入学习。

我们为学员提供了良好的培训环境:专门的培训教室、可口的美食、舒适的住宿条件、动力十足的学习伙伴,以及随时答疑解惑的指导老师。

你同样需要类似的良好环境。因此,应保证充足的睡眠,找一个安静的地方开始学习。参考以下建议也很有帮助:

(1) 组织朋友或同事组成兴趣小组学习;

(2) 集中安排时间逐章学习;

(3) 参与本书论坛的交流讨论(forums.bignerdranch.com);

(4) 寻求Android开发高手的帮助。

本书内容

本书带你学习开发8个Android应用。有些应用很简单,一章即可讲完;有些则相对复杂。最复杂的一个应用跨越了13章。通过这些精心编排的应用,你能学到很多重要的理论知识和开发技巧,并获得最直接的开发经验。● GeoQuiz本书的第一个应用,借此学习Android应用的基本组成、

activity、界面布局以及显式intent。● CriminalIntent本书中最复杂的应用,用来记录办公室同事的种种陋习。借

此应用学习fragment、主从用户界面、list-backed用户界面、菜

单选项、相机调用、隐式intent等内容。● BeatBox一个可以震慑坏人的应用,借此深入学习fragment、媒体文

件的播放与控制、MVVM架构、数据绑定、单元测试、主题以及

drawable资源。● NerdLauncher一个个性化启动器,借此深入学习intent以及Android任务。● PhotoGallery一个从Flickr网站下载并显示照片的客户端应用,借此学习

Android服务、多线程、网络内容下载等知识。● DragAndDraw一个简单的画图应用,借此学习触摸手势事件处理以及如何

创建个性化视图。● Sunset一个漂亮的日落动画应用,借此学习Android动画。● Locatr一个查询当前位置的Flickr图片并显示在地图上的应用。借

此应用学习如何使用定位服务和地图。挑战练习

大部分章末都配有练习题。可借此机会学以致用,查阅官方文档,锻炼独立解决问题的能力。

强烈建议你完成这些挑战练习。在练习过程中,尝试另辟蹊径,探索自己独特的学习之路。这有助于巩固所学知识,增强未来开发应用的信心。

若遇到一时难以解决的问题,请访问论坛http://forums.bignerdranch.com求助。深入学习

部分章末还包含一块名为“深入学习”的内容。这些内容针对相应章节的知识点,提供深入讲解或更多学习信息。本部分内容不属于必须掌握的部分,但还是希望你有兴趣阅读并有所收获。

编码风格

有别于其他Android开发学习社区的编码风格,我们有自己的偏好,主要有以下两个方面。● 在监听器代码部分使用匿名内部类这纯属个人偏好。我们认为,使用匿名内部类,代码可以更

简练,监听器实现方法更一目了然。尽管在高性能要求的场景下

或大型应用中,匿名内部类可能会有一些问题,但大多数情况下

没有问题。● 自第7章引入fragment后,后续所有用户界面都使用它我们有理由坚持这一点。相信我们,使用得当的话,

fragment就是Android开发人员手中的一大利器。一旦适应,用起

来也没那么难。相比activity,fragment在创建和显示用户界面时

更加灵活,优势明显,值得为此付出努力。

版式说明

为方便阅读,本书会对某些特定内容采用专门的字体。变量、常量、类型、类名、接口名和方法名会以代码体显示。

所有代码与XML清单也会以代码体显示。需要输入的代码或XML总是以粗体显示。应该删除的代码或XML会打上删除线。例如,在以下实现代码里,我们删除了makeText(...)方法的调用,增加了checkAnswer(true)方法的调用。@Overridepublic void onClick(View v) { Toast.makeText(QuizActivity.this, R.string.incorrect_toast, Toast.LENGTH_SHORT).show(); checkAnswer(true);}

Android版本

本书教学主要针对当前广泛使用的各个系统版本(Android 4.4 至 Android 7.1)。虽然更老的系统版本仍有人在用,但对于大多数开发者来说,为这部分人开发应用就是个赔本的买卖。如果应用确实需要支持 Android 4.4 之前的系统版本,请参考本书第2版(Android 4.1及以上版本)和第1版(Android 2.3及以上版本)的相关内容。

Google还会不断地发布新版本的Android系统。请放心,Android支持向后兼容(详见第6章),即便有了新系统,本书所授知识也不会过时。而且,通过forums.bignerdranch.com论坛,我们也会不断跟踪Android开发新动向,及时为你提供开发指导和支持。

电子书

扫描如下二维码,即可购买本书电子版。

 

开发必备工具

开始学习前,你需要安装Android Studio。基于流行的IntelliJ IDEA创建,Android Studio是用于Android开发的一套集成开发工具。

Android Studio的安装包括如下内容。● Android SDK最新版本的Android SDK。● Android SDK工具和平台工具用来测试与调试应用的一套工具。● Android模拟器系统镜像用来在不同虚拟设备上开发和测试应用。

撰写本书时,Google一直在积极开发和更新Android Studio版本。因此,请注意了解当前版本和本书所用版本之间的差异。如需帮助,请访问forums.bignerdranch.com论坛。

Android Studio的下载与安装

可以从Android开发者网站下载Android Studio:developer.android.com/sdk/。

首次安装的话,还需从www.oracle.com下载并安装Java开发工具箱(JDK 8)。

如仍有疑问,请访问网址developer.android.com/sdk/寻求帮助。

下载早期版本的SDK

Android Studio自带最新版本的SDK和模拟器系统镜像。若想在Android早期版本上测试应用,还需额外下载相关工具组件。

可通过Android SDK管理器来配置安装这些组件。在Android Studio中,选择Tools → Android → SDK Manager菜单项,如图0-1所示。(已创建并打开了新项目时,Tools菜单才可见。还没创建过项目的话,可在Android开发向导界面,在Quick Start区域,选择Configure → SDK Manager来启动SDK管理器。)

图0-1 Andriod SDK管理器

选择并安装需要的Android版本和工具。下载这些组件需要一定时间,请耐心等待。

通过Android SDK管理器,还可以及时获取Android最新发布内容,比如新系统平台或新版本工具等。

硬件设备

模拟器是测试应用的好帮手,但需测试应用性能时,物理Android设备无可替代。如果手头有物理设备,建议按需使用。

 第 1 章Android开发初体验

本章将带你开发本书第一个应用,并借此学习一些Android基本概念以及构成应用的UI组件。学完本章,如果没能全部理解,也不必担心,后续章节还会涉及这些内容并有更加详细的讲解。

马上要开发的应用名叫GeoQuiz,它能给出一道道地理知识问题。用户点击TRUE或FALSE按钮来回答屏幕上的问题,GeoQuiz即时作出反馈。

图1-1显示了用户点击TRUE按钮的结果。

图1-1 你是澳洲人吗1.1 Android开发基础

GeoQuiz应用由一个activity和一个布局(layout)组成。● activity是Android SDK中Activity类的一个实例,负责管理用

户与应用界面的交互。应用的功能是通过编写Activity子类来实现的。对于简单的应

用来说,一个Activity子类可能就够了,而复杂的应用则会有多个。GeoQuiz是个简单应用,因此它只有一个名叫QuizActivity的

Activity子类。QuizActivity管理着图1-1所示的用户界面。● 布局定义了一系列用户界面对象以及它们显示在屏幕上的位

置。组成布局的定义保存在XML文件中。每个定义用来创建屏幕

上的一个对象,如按钮或文本信息。GeoQuiz应用包含一个名叫activity_quiz.xml的布局文件。该

布局文件中的XML标签定义了图1-1所示的用户界面。

QuizActivity与activity_quiz.xml文件的关系如图1-2所示。

图1-2 QuizActivity管理着activity_quiz.xml文件定义的用户界面

有了这些Android基本概念之后,我们来创建GeoQuiz应用。1.2 创建Android项目

首先我们创建一个Android项目。Android项目包含组成一个应用的全部文件。

启动Android Studio程序,首次运行的话,会看到如图1-3所示的欢迎界面。

图1-3 欢迎使用Android Studio

在欢迎界面,选择创建Android Studio新项目选项(Start a new Android Studio project);非首次运行的话,选择File → New → New Project…菜单项。

现在,你应该打开了新建项目向导界面,如图1-4所示。在此界面的应用名称(Application name)处输入GeoQuiz。在公司域名(Company Domain)处输入android.bignerdranch.com。此时自动产生的包名称(Package name)会变为com.bignerdranch.android.geoquiz。至于项目存储位置(Project location),就看个人喜好了。

图1-4 创建新项目

注意,以上包名称遵循了“DNS反转”约定,也就是将企业组织或公司的域名反转后,在尾部附加上应用名称。遵循此约定可以保证包名称的唯一性,这样,同一设备和Google Play商店的各类应用就可以区分开来。

单击Next按钮,接下来配置应用支持哪些版本的Android设备。GeoQuiz应用只能在手机上运行,所以这里勾选Phone and Tablet选项。SDK最低版本选择API 19: Android 4.4(KitKat),如图1-5所示。第6章会介绍Android不同SDK版本的差异。

图1-5 设备支持配置

单击Next按钮继续。

在接下来的窗口中,需要为GeoQuiz应用的启动初始屏选择模板,如图1-6所示。选择Empty Activity后单击Next按钮继续。(Android Studio更新频繁,因此新版本的向导界面可能与本书略有不同。这不是什么大问题,一般来讲,工具更新后,向导界面的配置选项应该不会有太大差别。如果大有不同,说明开发工具有了重大更新。不要担心,请访问本书论坛 forums.bignerdranch.com,我们会教你如何使用新版本的开发工具。)

图1-6 选取activity类型(空activity)

在应用向导的最后一个窗口,命名activity子类为QuizActivity,如图1-7所示。注意子类名的Activity后缀。尽管不是必需的,但最好是遵循这种规范的命名约定。

图1-7 配置activity

确认Generate Layout File选项已勾选。为体现布局与activity间的对应关系,布局名(Layout Name)会自动更新为activity_quiz。布局的命名规则是:颠倒activity子类名的单词顺序并全部转小写,然后在单词间添加下划线。对于后续章节中的所有布局以及将要学习的其他资源,都建议采用这种命名风格。

如果你的Android Studio版本还有其他选项,请保持默认选择不变。单击Finish按钮,Android Studio会完成创建并打开新项目。1.3 Android Studio使用导航

如图1-8所示,Android Studio已在工作区窗口里打开新建项目。

整个工作区窗口分为不同的区域,这里统称为工具窗口(tool window)。

图1-8 新的项目窗口

左边是项目工具窗口(project tool window),通过它可以查看和管理所有与项目相关的文件。

主视图是代码编辑区(editor)。为便于开发,Android Studio已在代码编辑区打开了QuizActivity.java文件。

点击工作区窗口左边、右边以及底部标有各种名称的工具按钮区域,可显示或隐藏各类工具窗口。当然,也可以直接使用它们对应的快捷键。假如看不到某个工具按钮的话,可以点击左下角的灰色方形区域或单击View → Tool Buttons菜单项找到它。1.4 用户界面设计

首先打开app/res/layout/activity_quiz.xml文件。如果看到的是布局预览界面,请点击底部的Text页切换显示XML代码。

当前,activity_quiz.xml文件定义了默认的activity布局。默认的XML布局文件内容经常有变,但相比代码清单1-1,一般不会有很大出入。代码清单1-1 默认的activity布局(activity_quiz.xml)

应用activity的默认布局定义了两个组件(widget):RelativeLayout和TextView。

组件是用户界面的构造模块。组件可以显示文字或图像,与用户交互,甚至布置屏幕上的其他组件。按钮、文本输入控件和选择框等都是组件。

Android SDK内置了多种组件,通过配置各种组件可获得所需的用户界面及行为。每一个组件都是View类或其子类(如TextView或Button)的一个具体实例。

图1-9展示了代码清单1-1中定义的RelativeLayout和TextView是如何在屏幕上显示的。

图1-9 显示在屏幕上的默认组件

不过,图1-9所示的默认组件并不是我们需要的,QuizActivity的用户界面需要下列组件:● 一个垂直LinearLayout组件;● 一个TextView组件;● 一个水平LinearLayout组件;● 两个Button组件。

图1-10展示了以上组件是如何构成QuizActivity用户界面的。

图1-10 布置并显示在屏幕上的组件

下面我们在activity_quiz.xml文件中定义这些组件。

在项目工具窗口中找到app/res/layout目录,打开activity_quiz.xml文件。对照代码清单1-2,修改文件内容。注意,需删除的XML已打上删除线,需添加的XML以粗体显示。本书统一使用这样的代码增删处理模式。代码清单1-2 在XML文件(activity_quiz.xml)中定义组件

参照代码清单输入代码,暂时不理解这些代码也没关系,你会在后续学习中逐渐弄明白的。注意,开发工具无法校验布局XML内容,拼写错误早晚会出问题,应尽量避免。

可以看到,有三行以android:text开头的代码出现了错误信息。暂时忽略它们,稍后会处理。

对照图1-10所示的用户界面查看XML文件,可以看出组件与XML元素一一对应。元素的名称就是组件的类型。

各元素均有一组XML属性。属性可以看作如何配置组件的指令。

为方便理解元素与属性的工作原理,接下来我们将以层级视角来研究布局。1.4.1 视图层级结构

组件包含在视图(View)对象的层级结构中,这种结构又称作视图层级结构(view hierarchy)。图1-11展示了代码清单1-2所示的XML布局对应的视图层级结构。

图1-11 布局组件的层级结构

从布局的视图层级结构可以看到,其根元素是一个LinearLayout组件。作为根元素,LinearLayout组件必须指定Android XML资源文件的命名空间属性,这里是http://schemas.android.com/apk/res/android。

LinearLayout组件继承自ViewGroup组件(也是个View子类)。ViewGroup组件是包含并配置其他组件的特殊组件。想要以一列或一排的样式布置组件,就可以使用LinearLayout组件。其他ViewGroup子类还有FrameLayout、TableLayout和RelativeLayout。

若某个组件包含在一个ViewGroup中,该组件与ViewGroup即构成父子关系。根LinearLayout有两个子组件:TextView和另一个LinearLayout。作为子组件的LinearLayout自己还有两个Button子组件。1.4.2 组件属性

下面来看看配置组件时常用的一些属性。01. android:layout_width和android:layout_height属性几乎每类组件都需要android:layout_width和

android:layout_height属性。以下是它们的两个常见属性值(二

选一)。● match_parent:视图与其父视图大小相同。● wrap_content:视图将根据其显示内容自动调整大小。(以前还有个fill_parent属性值,等同于match_parent,现已

废弃不用。)根LinearLayout组件的高度与宽度属性值均为

match_parent。LinearLayout虽然是根元素,但它也有父视图

——Android提供该父视图来容纳应用的整个视图层级结构。其他包含在界面布局中的组件,其高度与宽度属性值均被设

置为wrap_content。请参照图1-10理解该属性值定义尺寸大小的

作用。TextView组件比其包含的文字内容区域稍大一些,这主要是

android:padding="24dp"属性的作用。该属性告诉组件在决定大

小时,除内容本身外,还需增加额外指定量的空间。这样屏幕上

显示的问题与按钮之间便会留有一定的空间,使整体显得更为美

观。(不理解dp的意思?dp即density-independent pixel,指与密

度无关的像素,详见第9章。)02. android:orientation属性android:orientation属性是两个LinearLayout组件都具有的属

性,它决定两者的子组件是水平放置还是垂直放置。根

LinearLayout是垂直的,子LinearLayout是水平的。子组件的定义顺序决定其在屏幕上显示的顺序。在垂直的

LinearLayout中,第一个定义的子组件出现在屏幕的最上端;而

在水平的LinearLayout中,第一个定义的子组件出现在屏幕的最

左端。(如果设备文字从右至左显示,如阿拉伯语或者希伯来语,

第一个定义的子组件则出现在屏幕的最右端。)03. android:text属性TextView与Button组件具有android:text属性。该属性指定组

件要显示的文字内容。请注意,android:text属性值不是字符串值,而是对字符串资

源(string resource)的引用。字符串资源包含在一个独立的名叫strings的XML文件中(strings.xml),虽然可以硬编码设置组件的文本属性值,如

android:text="True",但这通常不是个好主意。比较好的做法

是:将文字内容放置在独立的字符串资源XML文件中,然后引用

它们。这样会方便应用的本地化(支持多国语言)。需要在activity_quiz.xml文件中引用的字符串资源还没添加。

现在就来处理。1.4.3 创建字符串资源

每个项目都包含一个默认字符串资源文件strings.xml。

在项目工具窗口中,找到app/res/values目录,展开目录,打开strings.xml文件。

可以看到,项目模板已经添加了一些字符串资源。如代码清单1-3所示,添加应用布局需要的三个新的字符串。代码清单1-3 添加字符串资源(strings.xml) GeoQuiz Canberra is the capital of Australia. True False(某些版本的Android Studio的strings.xml默认带有其他字符串,请勿删除它们,否则会引发与其他文件的联动错误。)

现在,在GeoQuiz项目的任何XML文件中,只要引用到@string/false_button,应用运行时,就会得到文本“False”。

保存strings.xml文件。这时,activity_quiz.xml布局缺少字符串资源的提示信息应该就消失了。(如仍有错误提示,请检查一下这两个文件,确认没有拼写错误。)

默认的字符串文件虽然已命名为strings.xml,你仍可以按个人喜好重命名。一个项目也可以有多个字符串文件。只要这些文件都放在res/values/目录下,含有一个resources根元素,以及多个string子元素,应用就能找到并正确使用它们。1.4.4 预览布局

至此,应用的界面布局已经完成,可以使用图形布局工具实时预览了。首先,确认保存了所有相关文件并且无错误发生,然后回到activity_quiz.xml文件,点击代码编辑区右边的Preview打开预览工具窗口(如果还没打开的话),如图1-12所示。

图1-12 在图形布局工具中预览布局(activity_quiz.xml)1.5 从布局XML到视图对象

知道activity_quiz.xml中的XML元素是如何转换为视图对象的吗?答案就在于QuizActivity类。

在创建GeoQuiz项目的同时,向导也创建了一个名叫QuizActivity的Activity子类。QuizActivity类文件存放在项目的app/java目录下。java目录是项目全部Java源代码的存放处。

在项目工具窗口中,依次展开app/java目录与com.bignerdranch.android.geoquiz包。找到并打开QuizActivity.java文件,查看其中的代码,如代码清单1-4所示。代码清单1-4 默认QuizActivity类文件(QuizActivity.java)package com.bignerdranch.android.geoquiz;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;public class QuizActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_quiz); }}(是不是不明白AppCompatActivity的作用?它实际就是一个Activity子类,能为Android旧版本系统提供兼容支持。第13章会详细介绍AppCompatActivity。)

如果无法看到全部类包导入语句,请单击第一行导入语句左边的⊕符号来显示它们。

该Java类文件有一个Activity方法:onCreate(Bundle)。(如果你的文件还包含onCreateOptionsMenu(Menu)和onOptionsItemSelected(MenuItem)方法,暂时不用理会。第13章会详细介绍它们。)

activity子类的实例创建后,onCreate(Bundle)方法会被调用。activity创建后,它需要获取并管理用户界面。要获取activity的用户界面,可调用以下Activity方法:public void setContentView(int layoutResID)

根据传入的布局资源ID参数,该方法生成指定布局的视图并将其放置在屏幕上。布局视图生成后,布局文件包含的组件也随之以各自的属性定义完成实例化。资源与资源ID

布局是一种资源。资源是应用非代码形式的内容,如图像文件、音频文件以及XML文件等。

项目的所有资源文件都存放在目录app/res的子目录下。在项目工具窗口中可以看到,activity_quiz.xml布局资源文件存放在res/layout/目录下。strings.xml字符串资源文件存放在res/values/目录下。

可以使用资源ID在代码中获取相应的资源。activity_quiz.xml布局的资源ID为R.layout.activity_quiz。

查看GeoQuiz应用的资源ID需要切换项目视图。Android Studio默认使用Android项目视图,如图1-13所示。为让开发者专注于最常用的文件和目录,默认视图隐藏了Android项目的真实文件目录结构。

图1-13 切换项目视图

在项目工具窗口的最上部找到下拉菜单,从Android项目视图切换至Project视图。Project视图会显示出当前项目的所有文件和目录。

展开目录app/build/generated/source/r/debug,找到项目包名称并打开其中的R.java文件,即可看到GeoQuiz应用当前所有的资源。R.java文件在Android项目编译过程中自动生成,如该文件头部的警示所述,请不要修改该文件的内容。

修改布局或字符串等资源后,R.java文件不会实时刷新。Android Studio另外还存有一份代码编译用的R.java隐藏文件。当前代码编辑区打开的R.java文件仅在应用安装至设备或模拟器前产生,因此只有在Android Studio中点击运行应用时,它才会得到更新。

R.java文件通常比较大,代码清单1-5仅展示了部分内容。代码清单1-5 GeoQuiz应用当前的资源ID(R.java)/* AUTO-GENERATED FILE. DO NOT MODIFY. * * This class was automatically generated by the * aapt tool from the resource data it found. It * should not be modified by hand. */package com.bignerdranch.android.geoquiz;public final class R { public static final class anim { ... } ... public static final class id { ... } public static final class layout { ... public static final int activity_quiz=0x7f030017; } public static final class mipmap { public static final int ic_launcher=0x7f030000; } public static final class string { ... public static final int app_name=0x7f0a0010; public static final int false_button=0x7f0a0012; public static final int question_text=0x7f0a0014; public static final int true_button=0x7f0a0015; }}

可以看到R.layout.activity_quiz即来自该文件。activity_quiz是R的内部类layout里的一个整型常量名。

GeoQuiz应用需要的字符串同样具有资源ID。目前为止,我们还未在代码中引用过字符串,如果需要,可以使用以下方法:setTitle(R.string.app_name);

Android为整个布局文件以及各个字符串生成资源ID,但activity_quiz.xml布局文件中的组件除外,因为不是所有组件都需要资源ID。在本章中,我们要在代码里与两个按钮交互,因此只需为它们生成资源ID即可。

本书主要使用Android项目视图,生成资源ID之前,记得切回。当然,如果你就喜欢使用Project视图,也没啥问题。

要为组件生成资源ID,请在定义组件时为其添加android:id属性。在activity_quiz.xml文件中,分别为两个按钮添加上android:id属性,如代码清单1-6所示。代码清单1-6 为按钮添加资源ID(activity_quiz.xml)

注意,android:id属性值前面有一个+标志,而android:text属性值则没有。这是因为我们在创建资源ID,而对字符串资源只是做引用。1.6 组件的实际应用

按钮有了资源ID,就可以在QuizActivity中直接获取它们。首先,在QuizActivity.java文件中增加两个成员变量。

在QuizActivity.java文件中输入代码清单1-7所示代码。(请勿使用代码自动补全功能。)代码清单1-7 添加成员变量(QuizActivity.java)public class QuizActivity extends AppCompatActivity { private Button mTrueButton; private Button mFalseButton; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_quiz); }}

文件保存后,会看到两个错误提示。没关系,稍后会处理。请注意新增的两个成员(实例)变量名称的m前缀。该前缀是Android编程应遵循的命名约定,本书将始终遵循该约定。

现在,将鼠标移至代码左边的错误提示处时,会看到两条同样的错误信息:Cannot resolve symbol 'Button'。

这告诉我们,需要在QuizActivity.java文件中导入android.widget.Button类包。可在文件头部手动输入以下代码:import android.widget.Button;

或者使用Option+Return(Alt+Enter)组合键,让Android Studio自动为你导入。代码有误时,也可以使用该组合键来修正。记得要常用。

类包导入后,刚才的错误提示应该就消失了。(如果仍然存在,请检查Java代码以及XML文件,确认是否存在输入或拼写错误。)

接下来,我们来编码使用按钮组件,这需要以下两个步骤:● 引用生成的视图对象;● 为对象设置监听器,以响应用户操作。1.6.1 引用组件

在activity中,可调用以下Activity方法引用已生成的组件:public View findViewById(int id)

该方法以组件的资源ID作为参数,返回一个视图对象。

在QuizActivity.java文件中,使用按钮的资源ID获取视图对象,赋值给对应的成员变量,如代码清单1-8所示。注意,赋值前,必须先将返回的View类型转换为Button。代码清单1-8 引用组件(QuizActivity.java)public class QuizActivity extends AppCompatActivity { private Button mTrueButton; private Button mFalseButton; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_quiz); mTrueButton = (Button) findViewById(R.id.true_button); mFalseButton = (Button) findViewById(R.id.false_button); }}1.6.2 设置监听器

Android应用属于典型的事件驱动类型。不像命令行或脚本程序,事件驱动型应用启动后,即开始等待行为事件的发生,如用户点击某个按钮。(事件也可以由操作系统或其他应用触发,但用户触发的事件更直观,如点击按钮。)

应用等待某个特定事件的发生,也可以说应用正在“监听”特定事件。为响应某个事件而创建的对象叫作监听器(listener)。监听器会实现特定事件的监听器接口(listener interface)。

无需自己动手,Android SDK已经为各种事件内置了很多监听器接口。当前应用需要监听用户的按钮“点击”事件,因此监听器需实现View.OnClickListener接口。

首先处理TRUE按钮。在QuizActivity.java文件中,在onCreate(Bundle)方法的变量赋值语句后输入下列代码,如代码清单1-9所示。代码清单1-9 为TRUE按钮设置监听器(QuizActivity.java) @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_quiz); mTrueButton = (Button) findViewById(R.id.true_button); mTrueButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // Does nothing yet, but soon! } }); mFalseButton = (Button) findViewById(R.id.false_button); }}(如果遇到View cannot be resolved to a type的错误提示,请使用Option+Return(Alt+Enter)快捷键导入View类。)

在代码清单1-9中,我们设置了一个监听器。按钮mTrueButton被点击后,监听器会立即通知我们。传入setOnClickListener(OnClickListener)方法的参数是一个监听器。它是一个实现了OnClickListener接口的对象。

使用匿名内部类

这里,一个匿名内部类(anonymous inner class)实现了OnClickListener接口。语法看上去稍显复杂,不过有个助记小技巧:最外层一对括号内的全部代码就是传入setOnClickListener(OnClickListener)方法的参数。mTrueButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // Does nothing yet, but soon! }});

本书所有的监听器都以匿名内部类来实现。这样做有两大好处。第一,使用匿名内部类,可以相对集中地实现监听器方法,一眼可见;第二,事件监听器一般只在一个地方使用,使用匿名内部类,就不用去创建繁琐的命名类了。

匿名内部类实现了OnClickListener接口,因此它也必须实现该接口唯一的onClick(View)方法。onClick(View)现在是个空方法。虽然必须实现onClick(View)方法,但具体如何实现取决于使用者,因此即使是个空方法,编译器也可以编译通过。(如果匿名内部类、监听器、接口等概念已忘得差不多了,现在就该去复习一下,或找本参考手册备查。)

参照代码清单1-10为FALSE按钮设置类似的事件监听器。代码清单1-10 为FALSE按钮设置监听器(QuizActivity.java) mTrueButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // Does nothing yet, but soon! } }); mFalseButton = (Button) findViewById(R.id.false_button); mFalseButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // Does nothing yet, but soon! } });}1.7 创建提示消息

接下来要实现的是,分别点击两个按钮,弹出我们称之为toast的提示消息。Android的toast是用来通知用户的简短弹出消息,用户无需输入什么,也不用做任何干预操作。这里,我们要用toast来反馈答案,如图1-14所示。

图1-14 toast消息反馈

首先回到strings.xml文件,如代码清单1-11所示,为toast添加消息显示用的字符串资源。代码清单1-11 增加toast字符串(strings.xml) GeoQuiz Canberra is the capital of Australia. True False Correct! Incorrect!

调用Toast类的以下方法,可创建toast:public static Toast makeText(Context context, int resId, int duration)

该方法的Context参数通常是Activity的一个实例(Activity本身就是Context的子类)。第二个参数是toast要显示字符串消息的资源ID。Toast类必须借助Context才能找到并使用字符串资源ID。第三个参数通常是两个Toast常量中的一个,用来指定toast消息的停留时间。

创建toast后,可调用Toast.show()方法在屏幕上显示toast消息。

在QuizActivity代码里,分别调用makeText(...)方法,如代码清单1-12所示。在添加makeText(...)时,可利用Android Studio的代码自动补全功能,让代码输入更轻松。

试读结束[说明:试读内容隐藏了图片]

下载完整电子书


相关推荐

最新文章


© 2020 txtepub下载