标签:
本章将通过设计首个应用(名为GeoQuiz)介绍编写Android应用需掌握的一些基概念和设计方法。
移动系统的的应用也叫App,本章的App能测试用户的地理知识。图1-1显示了用户点击“错”按钮的结果。
图1-1 正确答案应该是台湾,而不是海南岛
GeoQuiz应用由一个activity(活动)和一个布局(layout)组成。
其中,Activity中文可以翻译为活动或者活动界面。
从用户角度来看, Activity就是包含用户界面的一个大组件,主要用于和用户进行交互。一个应用程序中可以包含1个或多个Activity。
从程序设计的角度来看,Activity是Android SDK中Activity类的一个具体实例,负责管理用户与信息屏的交互。Android应用程序的功能是通过编写一个个Activity子类来实现的。简单的应用可能只需一个子类,而复杂的应用则会有多个子类。
本章的GeoQuiz应用很简单,因此它只有一个Activity名为 QuizActivity (继承自 Activity 的子类)。QuizActivity 负责管理 图1-1所示的用户界面。
布局(layout)定义了一系列用户界面对象以及它们显示在屏幕上的位置。组成布局的定义保存在XML文件中。每个定义用来创建屏幕上的一个对象,如按钮或文本信息。
GeoQuiz应用包含一个名为activity_quiz.xml的布局文件,该文件中的XML标签定义了图1-1所示的用户界面。
通常,一个Activity对应一个layout(布局),如QuizActivity的布局是activity_quiz.xml文件。在本章中,QuizActivity管理着activity_quiz.xml文件定义的用户界面,它们之间的关系如图1-2所示。
图1-2 Activity、布局文件和用户界面关系图
学习了这些基本概念后,我们来创建本书第一个应用。
首先,在根目录下建一个目录,用来保存项目文件。英文命名,比如F:\Mywork\AS\ch1\,代表第一章的工程目录。
接下来,启动Android Studio 程序,选择右侧 Start a new Android Studio project菜单项;此时,Android Studio打开一个向导来帮助我们来创建一个新的项目。
在第一个向导窗口中,在应用名称(Application Name)处输入GeoQuiz,在公司域名(Company Domain)处输入jet.com(其中jet是我的英文名),如图1-3所示。此时包名处(Package Name)会自动更新为com.jet.geoquiz。
在项目位置处(Project location)选择一个合适位置,不要有中文路径,如F:\Mywork\AS\ch1\,其中AS 代表Android 学习、ch1代表第一章。
图1-3 创建新应用
注意,以上输入的包名遵循了“DNS反转”约定,亦即将个人或公司的域名反转后,在尾部附加上应用名称。遵循此约定可以保证包名的唯一性,这样,同一设备和Google Play商店的各类应用就可以区分开来。
l Application Name此处填写想呈现给用户的应用名称,此处我们使用“GeoQuiz”。
l Company domain 包名限定符,Android Studio会将这个限定符应用于每个新建的Android项目。
l Package Name是应用的包命名空间(同Java的包的概念),我们也可以独立地编辑该包名。
l Project location 存放项目的目录。
现在单击Next按钮。
接下来的四个选项用来配置应用如何与不同版本的Android设备适配。GeoQuiz应用只需使用默认设置,其他选项忽略。
Android开发工具每年会更新多次,因此当前的向导画面看起来可能会与图1-4略有不同。这一般不是问题,工具更新后,向导画面的配置选项应该不会有太大差别。
图1-4 选择App运行的Android版本
现在单击Next按钮。
图1-5所示的窗口询问想要创建的activity类型。选择Blank Activity。
图1-5 创建一个Blank activity
单击Next按钮继续
在应用向导的最后一个窗口,命名activity子类为QuizActivity
,如图1-6所示。
图1-6 配置建的activity
最后,单击Finish按钮。Android Studio完成创建并打开新的项目。(有时还是漫长的等待… L)
如图1-7所示(可放大),第一次运行 Android Studio时工作区窗口会打开多个视图,熟悉后,可以按需开关某些视图。
图1-7 调整安排工作区窗口
整个工作区窗口分为不同的区域,这里统称为视图。最左边视图1是项目导航(Project)视图,通过它可以管理所有项目相关的文件。项目导航视图里的目录结构可以设置为“Android”或者“Project”类型,点击图1-7左上角红框可完成设置。我们采用“Android”结构显示项目文件目录;
中间部分视图2是UI设计区和代码编辑区视图。Android Studio默认在中间部分显示UI设计区 (打开 activity_quiz.xml文件)。
在工作区的底部视图3还有一些其他视图,显示一些编译信息、警告或建议信息、代码调试信息等。
工作区的每个视图都以分组面板(tab group)形式显示,可切换不同分组显示不同视图。
注:有时不小心关闭或隐藏了某些视图,按Shift+F12还原。
通常,Android Studio向导会帮我们生成一个布局文件activity_quiz.xml。布局文件统一放置在\app\res\layout\目录, 所有layout文件都放在这里。
如图1-7所示,在中间部分已默认打开activity_quiz.xml布局文件,并在图形布局工具Design里显示了预览界面。虽然图形化布局工具非常好用,但为更好地理解布局的内部原理,我们还是先学习如何使用XML代码来定义布局。
在中间部分视图2的底部选择标为Text的标签页,从布局界面Design切换到XML代码界面Text。
余下内容,请参考教材,理解和完成... ...
代码清单1-1 基本activity布局(activity_quiz.xml)
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".QuizActivity" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:text="@string/hello_world" />
</RelativeLayout>
代码清单1-2 在XML文件(activity_quiz.xml)中定义组件
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".QuizActivity" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:text="@string/hello_world" />
</RelativeLayout>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="24dp"
android:text="@string/question_text" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/true_button" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/false_button" />
</LinearLayout>
</LinearLayout>
1.4.1 视图层级结构
组件包含在视图对象的层级结构,即视图层级结构(view hierarchy)中。图1-10展示了代码清单1-2所示XML布局对应的视图层级结构。
图1-10 布局中组件及属性的层级结构
余下内容,请参考教材,理解和完成... ...
1.4.2 组件属性
请参考教材,理解和完成本节内容... ...。
1.4.3 创建字符串资源
每个项目都包含一个名为strings.xml的默认字符串文件。
在项目导航视图中,找到res\values目录,然后打开strings.xml文件。可以看到,项目模版已经默认添加了一些字符串资源。删除不需要的hello_world部分,添加应用布局需要的三个新的字符串,如代码清单1-3所示。
代码清单1-3 添加字符串资源(strings.xml)
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">GeoQuiz中国地理_ch1</string>
<string name="hello_world">Hello, world!</string>
<string name="question_text">中国最大的岛屿---海南岛.</string>
<string name="true_button">对</string>
<string name="false_button">错</string>
<string name="action_settings">Settings</string>
</resources>
现在,在GeoQuiz项目的任何XML文件中,只要引用到@string/false_button
,应用运行时,就会得到文本“错”。
1.4.4 预览界面布局
至此,应用的界面布局已经完成,现在我们使用图形布局工具来进行实时预览。首先,确认保存了所有相关文件并且无错误发生,然后回到activity_quiz.xml文件,在编辑区底部选择图形布局标签页进行界面布局预览,如图1-11所示。
图1-11 在图形布局工具中预览界面布局(activity_quiz.xml)
上一节,GeoQuiz应用的用户界面设计已经做好,但这仅仅是个静态的界面,用户还无法通过界面与我们的程序交互。如何处理这个问题?
想要实现交互,程序必须要知道用户在用户界面上做了那些动作,然后程序才能作出相应的反应(也叫响应用户事件),如何实现?
l 首先,程序要知道用户界面上有哪些组件对象,即将布局里的“界面元素”内容转换为视图对象。
l 然后,程序要时刻监听视图对象,如果用户与这些对象进行交互(如点击按钮),程序要做出反应。(在GeoQuiz应用中,程序要做出的反应就是“告诉用户的选择是否正确“)
本节先解决第一个问题:程序要知道用户界面上有哪些组件对象,即将布局里的“界面元素”内容转换为视图对象。
activity_quiz.xml 是XML类型的文件,是用来定义用户界面的布局文件。文件每个 XML元素对应一个“界面元素”。那么它是如何转换为视图对象的?答案就在 QuizActivity
类中。
在创建 GeoQuiz 项目的同时,也创建了一个名为 QuizActivity
类,它是 Activity
子类。QuizActivity
类文件存放在项目的\app\java\包目录下。
在项目导航视图中,依次展开\app\java\com.jet.geoquiz\, 打开QuizActivity.java文件,删除所有代码,按照代码清单1-4重新输入(默认代码是由向导自动生成的,目前我们不需要)。
现在逐行查看其中的代码。
代码清单1-4 QuizActivity
的默认类文件(QuizActivity.java)
package com.jet.geoquiz;
import android.app.Activity;
import android.os.Bundle;
public class QuizActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_quiz);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_quiz, menu);
return true;
}
}
代码清单1-6 为按钮添加资源ID(activity_quiz.xml)
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" ... >
...
<Button
android:id="@+id/true_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/true_button" />
<Button
android:id="@+id/false_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/false_button" />
</LinearLayout>
</LinearLayout>
既然按钮有了资源ID,就可以在QuizActivity
中直接获取它们。首先,在QuizActivity.java文件中增加两个成员变量。如代码清单1-8所示代码:
代码清单1-8 添加成员变量(QuizActivity.java)
public class QuizActivity extends Activity {
private Button mTrueButton;
private Button mFalseButton;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_quiz);
}
}
文件保存后,(如果是手工录入的)可看到两个错误提示(Button 变红色)。没关系,这点错误马上搞定。
现在,请将鼠标移至“红色Button”处,可看错误提示:Cannot resolve symbol ‘Button’.
该错误提示告诉我们需要在QuizActivity.java文件中导入android.widget.Button
类包。可在文件头部手动输入以下代码:
import android.widget.Button;
或者采用下面介绍的便捷方式自动导入。
1.6.1 使用Alt+Enter快捷键
使用Alt+Enter快捷键,可以帮助我们快速更正错误;
当你在错误代码附近按下组合键Alt+Enter时, Android Studio会依据代码自动帮你修正错误。包括,帮你决定应该导入哪些Java或Android SDK类包、修正简单语法错误。
对于上面的错误(Button 变红色)如果还没有解决,按下组合键Alt+Enter红色错误提示应该就会消失了。(如错误提示仍在,请检查代码是否拼写错误)
接下来,我们通过以下两个步骤,就能使用布局文件里的两个按钮:
l 引用组件:引用生成的视图对象;
l 设置监听器:为对象设置监听器,以响应用户操作。
1.6.2 引用组件
在activity中,可通过以下Activity
类
提供的findViewById方法引用已生成的组件:
public View findViewById(int id)
该方法接受组件的资源ID作为参数,返回一个视图对象。
在QuizActivity.java文件中,使用按钮的资源ID获取生成的对象后,赋值给对应的成员变量,如代码清单1-9所示。注意,赋值前,必须先将返回的View
转型(cast)为Button
。
代码清单1-9 引用组件(QuizActivity.java)
public class QuizActivity extends Activity {
private Button mTrueButton;
private Button mFalseButton;
@Override
public 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);
}
}
文件保存后,如果有错误提示,检查一下activity_quiz.xml和strings.xml文件,看看里面是不是有错误. 修改错误后重新保存所有文件。
Check Point:
1.2为什么利用Activity
类
提供的findViewById方法,就可以把成员变量与按钮资源绑定?
答: findViewById可以利用某个资源的ID返回其的引用(相当于在你家安装一个带遥控功能的智能摄像头),将这个引用赋值给(指向)成员变量 ,实现了绑定.(这里的指向,相当于把摄像头连线到你手机)
1.3 为什么赋值前,必须先将返回的View
转型(cast)为Button
?
答: Button类 extends TextView。
1.6.3 设置监听器
请参考教材,理解和完成本节内容... ...
代码清单1-10 为True按钮设置监听器(QuizActivity.java)
...
@Override
public 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);
}
}
代码清单1-11 为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!
}
});
}
创建提示消息
接下来要实现的就是,分别单击两个按钮,弹出我们称为toast的提示消息。Android的toast指用来通知用户的简短弹出消息,但无需用户输入或做出任何操作。这里,我们要做的就是使用toast来告知用户其答案正确与否,如图1-12所示:
图1-12 toast反馈消息提示
首先回到strings.xml文件,如代码清单1-12所示,为toast添加消息显示用的字符串资源。
代码清单1-12 增加toast字符串(strings.xml)
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">中国地理</string>
<string name="question_text">中国最大的岛屿---海南岛.</string>
<string name="true_button">对</string>
<string name="false_button">错</string>
<string name="correct_toast">正确!</string>
<string name="incorrect_toast">错误!</string>
<string name="action_settings">Settings</string>
</resources>
通过调用来自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-13所示。在添加makeText()
时,可利用Android Studio的代码自动补全功能,让代码输入工作更加轻松。
代码清单1-13 创建提示消息(QuizActivity.java)
...
mTrueButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(QuizActivity.this,
R.string.incorrect_toast,
Toast.LENGTH_SHORT).show();
}
});
mFalseButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(QuizActivity.this,
R.string.correct_toast,
Toast.LENGTH_SHORT).show();
}
});
要运行Android应用,需使用硬件设备或者虚拟设备(virtual device)。包含在开发工具中的Android设备模拟器可提供多种虚拟设备。(也可以使用海马玩模拟器 Droid4X等虚拟机)
要想创建Android虚拟设备(AVD),在Android Studio中,选择Tools->Android->AVD Manager菜单项,当AVD管理器窗口弹出时,点击窗口左下的Create Virtual Device按钮。
在随后弹出的对话框中,可以看到有很多配置虚拟设备的选项。按照 一系列图1-13所示进行配置。
图1-13-1 创建新的AVD
接下来,选择要模拟的手机(尽量选择低版本手机,速度快),建议选择Nexus S,如下图:
图1-13-2 选择要模拟的手机(Select Hardware)
接下来,选择一个系统镜像(Android版本和虚拟机CPU),Level17 ,x86,如下图:
图1-13-3 选择要模拟的手机(Select Hardware)
最后,给新建的AVD命名、设置显示比例等,默认就好,如下图:
图1-13-4 AVD命名、设置显示比例等
AVD创建成功后,我们用它运行GeoQuiz应用:
l 首先,选择Tools->Android->AVD Manager菜单项,运行之前新建的虚拟机(有点慢)
l 然后,在菜单Run->Edit Configurations 里选择GeoQuiz
l 最后,选择Run->Run ‘GeoQuiz’, 运行GeoQuiz应用。
Android会列表让你选择当前的虚拟机或实体机设备如图1-14,然后安装应用包(APK)并运行应用。
图1-14 AVD命名、设置显示比例等
启动虚拟机可能比较耗时,请耐心等待。设备启动完成,应用运行后,就可以在应用界面点击按钮,让toast告诉我们答案。(注意,如果应用启动运行后,我们凑巧不在电脑旁,回来时,就可能需要解锁AVD。如同一台真实设备,AVD闲置一定时间会自动锁上。)
如何你没有实体机,建议保持模拟器一直运行,这样就不必在反复运行调试应用时,痛苦地等待AVD启动了。单击回退按钮(即AVD模拟器上的U型箭头按钮)可以停止应用。需要调试变更时,再通过Android Studio重新运行应用。
虽然模拟器非常有用,但在真实设备上测试应用能够获得更准确的结果。在第2章中,我们将在真实硬件设备上运行GeoQuiz应用,并且为GeoQuiz应用添加更多地理知识问题,以供用户回答。
请参考教材,理解和完成本节内容... ...
标签:
原文地址:http://www.cnblogs.com/jlxuqiang/p/4740979.html