1.3 构建简单的用户界面
在本课中,您将使用 Android Studio Layout Editor 创建一个布局,其中包括一个文本框和一个按钮。在下一课中,您会将文本框的内容发送到另一个 Activity,让应用响应按钮点按操作。
Android 应用的界面使用布局(ViewGroup
对象)和微件(View
对象)层次结构构建。布局是一种不可见的容器,用于控制其子视图在屏幕上的位置。微件是界面组件,例如按钮和文本框。
图 2.ViewGroup
对象如何在布局中形成分支并容纳 View
对象的图解
Android 为 ViewGroup
和 View
类提供了一个 XML 词汇,因此您的大多数界面都在 XML 文件中定义。不过,本课将向您介绍如何使用 Android Studio Layout Editor 创建布局,而不是教您编写一些 XML 代码。在布局编辑器中,只需拖放视图即可构建布局,大大简化了构建工作。
打开布局编辑器
注:本课假设您使用 Android Studio 3.0,并且已完成上一课创建 Android 项目的学习。
首先,请按照以下步骤设置您的工作区:
- 在 Android Studio 的 Project 窗口中,打开 app > res > layout > activity_main.xml。
- 要为布局编辑器留出更多空间,请选择 View > Tool Windows > Project 以隐藏 Project 窗口,或者点击 Android Studio 左侧的 Project )。
- 如果您的编辑器显示 XML 源代码,请点击窗口底部的 Design 标签。
- 点击 Select Design Surface 并选择 Blueprint。
- 点击工具栏中的 Show 并确保选中 Show Constraints。
- 确保 Autoconnect 关闭。工具栏中的提示应为 Turn On Autoconnect (因为它现在处于关闭状态)。
- 点击工具栏中的 Default Margins, 然后选择 16(您稍后仍然可以调整每个视图的外边距)。
- 点击工具栏中的 Device in Editor, 然后选择 Pixel XL。
您的编辑器现在应如图 3 所示。
左下方的 Component Tree 窗口显示布局的视图层次结构。在本例中,根视图是 ConstraintLayout
,仅包含一个 TextView
对象。
ConstraintLayout
是一种布局,它根据同级视图和父布局的约束条件为每个视图定义位置。这样一来,您可以创建具有扁平视图层次结构的简单布局和复杂布局。也就是说,它可以避免对嵌套布局(布局内的布局,如图 2 所示)的需求,嵌套布局会增加绘制界面所需的时间。
例如,您可以声明以下布局(在图 4 中):
- 视图 A 显示在父布局上方 16dp 处。
- 视图 A 显示在父布局左侧 16dp 处。
- 视图 B 显示在视图 A 右侧 16dp 处。
- 视图 B 与视图 A 的顶部对齐。
在后面几部分中,您将构建一个与此布局类似的布局。
添加一个文本框
- 首先,您需要移除布局中已有的内容。因此,请点击 Component Tree 窗口中的 TextView,然后按 Delete。
- 在左侧的 Palette 窗口中,点击左侧窗格中的 Text,然后将 Plain Text 拖放到设计编辑器中靠近布局顶部的位置。这是一个接受纯文本输入的
EditText
微件。 - 在设计编辑器中点击视图。现在,您可以在每个角上看到大小调整手柄(正方形),并在每个边上看到约束锚点(圆形)。
为了能更好地控制,您可能需要使用工具栏中的按钮放大编辑器。
- 点击并按住顶边上的锚点,将其向上拖动,直至锚点吸附到布局的顶部,然后释放。这是一个约束条件 - 它指定视图应位于距离布局顶部 16dp 的位置(因为您将默认外边距设置为 16dp)。
- 类似地,从视图左侧创建一个约束条件,将其限制在布局左侧。
结果应如图 5 中的屏幕截图所示。
添加一个按钮
- 在 Palette 窗口中,点击左侧窗格中的 Widgets,然后将 Button 拖放到设计编辑器中靠近右侧的位置。
- 从按钮左侧创建一个约束条件,将其限制在文本框的右侧。
- 要在水平对齐中约束视图,您需要在文本基线之间创建一个约束条件。因此,请点击按钮,然后点击 Edit Baseline, 它将显示在设计编辑器中选定视图的正下方。基线锚点显示在按钮内部。点击并按住此锚点,然后将其拖动到文本框中显示的基线锚点。
结果应如图 6 中的屏幕截图所示。
注:您还可以使用顶部或底部边缘创建水平对齐,不过,按钮在其图像周围包含内边距,因此如果您按照这种方式对齐这些视图,视觉对齐将是错误的。
更改界面字符串
要预览界面,请点击工具栏中的 Select Design Surface 并选择 Design。请注意,文本输入使用“Name”预填充,按钮标记为“Button”。现在,您将更改这些字符串。
- 打开 Project 窗口,然后打开 app > res > values > strings.xml。
这是一个字符串资源文件,您应在这个文件中指定所有界面字符串。这样您可以在一个位置管理所有界面字符串,让字符串的查找、更新和本地化变得更加容易(与您的布局或应用代码中的硬编码字符串相比)。
- 点击编辑器窗口顶部的 Open editor。这将打开 Translations Editor,它为添加和编辑您的默认字符串提供了一个简单的界面,并且有助于保持您的所有已翻译字符串井然有序。
-
- 为键名输入“edit_message”。
- 为值输入“Enter a message”。
- 点击 OK。
- 再添加一个名称为“button_send”并且值为“Send”的键。
现在,您可以为每个视图设置这些字符串。点击标签栏中的 activity_main.xml 以返回布局文件,然后按照以下步骤添加字符串:
- 点击布局中的文本框,如果 Attributes 窗口在右侧还未显示,请点击右侧边栏上的 Attributes 。
- 找到 text 属性(当前设为“Name”)并删除值。
- 找到 hint 属性,然后点击文本框右侧的 Pick a Resource 。在出现的对话框中,双击列表中的 edit_message。
- 现在,点击布局中的按钮,找到 text 属性,点击 Pick a Resource, 然后选择 button_send。
让文本框大小灵活调整
要创建一个可以适应不同屏幕尺寸的布局,您现在将让文本框拉伸以填充剩余的所有水平空间(扣除按钮和所有外边距后的空间)。
首先,请点击工具栏中的 Show 并选择 Blueprint。
- 选择两个视图(点击一个,按住 Shift 并点击另一个),然后右键点击任何一个视图并选择 Chain > Create Horizontal Chain。
链是两个或更多视图之间的双向约束条件,它让您可以采用一致的方式放置链接的视图。
- 选择按钮并打开 Attributes 窗口。使用 Attributes 窗口顶部的视图检查器将右外边距设置为 16。
- 现在,点击文本框以查看其属性。点击两次宽度指示器,确保将其设置为 Match Constraints,如图 9 中的标注 1 所示。
“Match constraints”表示宽度将延长以符合水平约束条件和外边距的定义。因此,文本框将拉伸以填充水平空间(扣除按钮和所有外边距后的空间)。
现在,布局已经完成,应如图 10 所示。
如果您的布局没有按照预计的效果显示,请点击下方链接,查看您的 XML 代码应当具有的外观,并将其与您在 Text 标签中看到的代码进行比较。(如果您的属性以不同顺序显示,没有问题。)
<?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout 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" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.example.myfirstapp.MainActivity"> <EditText android:id="@+id/editText" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginStart="16dp" android:layout_marginTop="16dp" android:ems="10" android:hint="@string/edit_message" android:inputType="textPersonName" app:layout_constraintEnd_toStartOf="@+id/button" app:layout_constraintHorizontal_bias="0.5" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> <Button android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginEnd="16dp" android:layout_marginStart="16dp" android:text="@string/button_send" app:layout_constraintBaseline_toBaselineOf="@+id/editText" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.5" app:layout_constraintStart_toEndOf="@+id/editText" /> </android.support.constraint.ConstraintLayout>
如需了解有关链和您可以对 ConstraintLayout
进行的所有其他操作的详细信息,请阅读使用 ConstraintLayout 构建自适应界面。
运行应用
如果已在上一课中将您的应用安装到设备上,只需点击工具栏中的 Apply Changes, 使用新布局更新应用。或者点击 Run, 安装并运行应用。
按钮仍然没有响应。要在点按按钮时启动另一个 Activity,请继续学习下一课。