3) 十分钟学会android--建立第一个APP,建立简单的用户界面
在本小节里,我们将学习如何用 XML 创建一个带有文本输入框和按钮的界面。下一节课将学会使 APP 对按钮做出响应——按钮被按下时,文本框里的内容被发送到另外一个 Activity。
Android 的图形用户界面由多个视图(View)和视图组(ViewGroup)构建而成。View 是通用的 UI 窗体小组件,如:按钮(Button)、文本框(Text field);而 ViewGroup 则是用来定义子视图布局的不可见的容器,如:网格部件(grid)、垂直列表部件(vertical list)。
Android 提供了一系列对应于 View 和 ViewGroup 子类的 XML 标签,以便我们用 XML 创建自己的 UI。
Layouts 是 ViewGroup 的子类。我们将在接下来的教程中练习如何使用 LinearLayout。

图 1 关于 ViewGroup 对象如何组织布局分支和包含其他 View 对象。
可选的布局文件
有很多理由使得我们选择在 XML 中定义界面布局,而不是在运行时动态生成布局。其中最重要的一点是——这可以让你为不同大小的屏幕创建不同的布局文件。例如,你可以创建两个版本的布局文件,告诉系统在小屏幕上使用其中一个布局文件,在大屏幕上使用另外一个布局文件。参见 兼容不同的设备。
创建一个 LinearLayout
在 Android Studio 中,从
res/layout目录打开content_my.xml文件。上一节创建新项目时生成的 BlankActivity 包含一个
content_my.xml文件,该文件根元素是一个包含 TextView 的 RelativeLayout。在 Preview 面板点击
关闭右侧 Preview 面板。在 Android Studio 中打开布局文件时,可以看到一个 Preview 面板。点击这个面板中的标签,可利用 WYSIWYG(所见即所得)工具在 Design 面板看到对应的图形化效果。但在本节中,我们将学习如何直接修改 XML 文件。
删除 [<TextView>] 标签。
把 [<RelativeLayout>] 标签改为 [<LinearLayout>]。
为 [<LinearLayout>] 添加 android:orientation 属性并设置值为
"horizontal"。去掉
android:padding属性和tools:context属性。
修改后结果如下:
res/layout/content_my.xml
<LinearLayout 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:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:showIn="@layout/activity_my">
LinearLayout 是 ViewGroup 的子类,用于放置水平或者垂直方向的子视图部件,放置方向由属性 android:orientation 决定。LinearLayout 里的子布局按照 XML 里定义的顺序显示在屏幕上。
所有的 Views 都会用到 android:layout_width 和 android:layout_height 这两个属性来设置自身的大小。
由于 LinearLayout 是整个视图的根布局,所以通过指定 width 和 height 属性为 "match_parent" 可以使其宽度和高度充满整个屏幕。该值表示子 View 扩张自己宽度和高度来 匹配 父控件的宽度和高度。
更多关于布局属性的内容,请参考 布局向导。
添加一个文本输入框
与其它 View 一样,我们需要定义 XML 里的某些属性来指定 EditText 的属性值。以下是应该在线性布局里指定的一些属性元素:
在
content_my.xml文件的 [<LinearLayout>] 标签内定义一个 [<EditText>] 标签,并设置id属性为@+id/edit_message。设置
layout_width和layout_height属性为wrap_content。设置
hint属性为一个名为edit_message的字符串。
代码如下:
res/layout/content_my.xml
<EditText android:id="@+id/edit_message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:hint="@string/edit_message" />
各属性说明:
android:id
这是视图的唯一标识符。可以在程序代码中通过该标识符引用对象。例如对这个对象进行读和修改的操作(在下一课里将会用到)。
当需要从 XML 里引用资源对象时,必须使用 @ 符号。紧随 @ 之后的是资源的类型(这里是 id),然后是资源的名字(这里使用的是 edit_message)。
+ 号只在第一次定义一个资源 ID 的时候需要。它是告诉 SDK——此资源 ID 需要被创建。在应用程序被编译之后,SDK 就可以直接使用这个 ID。edit_message 是在项目文件 gen/R.java 中创建一个新的标识符,这个标识符和 EditText 关联。一旦资源 ID 被创建了,其他资源如果引用这个 ID 就不再需要 + 号。
android:layout_width 和 android:layout_height
不建议指定宽度和高度的具体尺寸,应使用 "wrap_content"。因为这样可以保证视图只占据内容大小的空间。如果你使用了 "match_parent",这时 EditText 将会布满整个屏幕,因为它将适应父布局的大小。参见 布局向导。
android:hint
当文本框为空的时候,会默认显示这个字符串。对于字符串 "@string/edit_message" 的值所引用的资源应该定义在单独的文件里,而不是直接使用字符串。因为使用的值是存在的资源,所以不需要使用 + 号。当然,由于你现在还没有定义字符串,所以在添加 @string/edit_message 的时候会出现编译错误。在下一节的教程中你将学会如何定义字符串资源,到时候就不会报错了。
资源对象
资源对象是与 APP 资源(如:位图、布局文件、字符串)关联的唯一整数。
在项目文件
gen/R.java中,每个资源都有一个与之对应的资源对象。你可以使用R类中的对象名称代指资源(如:在指定 android:hint 属性时需要的字符串)。同时,也可以通过 android:id 属性随时为 View 创建资源 ID,以便在代码中引用这个 View。每次编译 APP 时,SDK 工具都会生成
R.java文件。所以,请永远不要修改这个文件。参阅 资源配备。
注:该字符串资源与 ID 使用了相同的名称(
edit_message)。然而,对于资源的引用是区分类型的(比如id和字符串),因此,使用相同的名称不会引起冲突。
增加字符串资源
默认情况下,你的 Android 项目包含一个字符串资源文件,即 res/values/string.xml。打开这个文件,为 "edit_message" 增加一个定义,其值为“Enter a message”。
在 Android Studio 里,编辑
res/values下的strings.xml文件。添加一个名为
"edit_message"的字符串,值为“Enter a message”。再添加一个名为
"button_send"的字符串,值为“Send”。下一节中将使用这个字符串创建按钮。
下边就是修改好的 res/values/strings.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">My First App</string>
<string name="edit_message">Enter a message</string>
<string name="button_send">Send</string>
<string name="action_settings">Settings</string>
</resources>
当你在用户界面定义一个文本时,应该把每一个文本字符串列入资源文件。这样做的好处是:对于所有字符串值,字符串资源能够单独的修改,在资源文件里你可以很容易的找到并且做出相应的修改。通过选择定义每个字符串,还允许你用不同语言本地化 APP。
更多关于不同语言本字符串资源本地化的问题,请参考 兼容不同的设备。
添加一个按钮
在 Android Studio 里,编辑
res/layout下的content_my.xml文件。在 [<LinearLayout>] 内部的 [<EditText>] 标签之后定义一个 [<Button>] 标签。
设置按钮的 width 和 height 属性值为
"wrap_content"以便让按钮的大小能完整显示文字。定义按钮的文本使用 android:text 属性,设置值为相似上一节中定义好的
button_send字符串资源。
此时的 [<LinearLayout>] 看起来应该是这样:
res/layout/content_my.xml
<LinearLayout 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:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:showIn="@layout/activity_my">
<EditText android:id="@+id/edit_message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:hint="@string/edit_message" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/button_send" />
</LinearLayout>
注:宽和高被设置为
"wrap_content",这时按钮占据的大小就是按钮里文本的大小。这个按钮不需要指定 android:id 的属性,因为 Activity 代码中不会引用该 Button。
当前 EditText 和 Button 部件只是适应了他们各自内容的大小,如图 2 所示:

图 2 EditText 和 Button 窗体小组件使用 "wrap_content" 作为宽度属性的值。
这样设置对按钮来说很合适,但是对于文本框来说就不太好了,因为用户可能输入更长的文本内容。因此如果能够占满整个屏幕宽度会更好。LinearLayout 使用 权重 属性达到这个目,即 android:layout_weight 属性。
权重的值指的是每个部件所占剩余空间的大小,该值与同级部件所占空间大小有关。这就类似于饮料的成分配方:“两份伏特加酒,一份咖啡利口酒”,即该酒中伏特加酒占三分之二。例如,我们定义一个权重为 2 的 View,另一个 View 的权重是 1,那么总数就是 3;这时第一个 View 占据 2/3 的空间,第二个占据 1/3 的空间。如果再加入第三个 View,权重设为 1,那么第一个 View(权重为 2 的)会占据 1/2 的空间,剩余的另外两个 View 各占 1/4。(请注意,使用权重的前提一般是给 View 的宽或者高的大小设置为 0dp,然后系统根据上面的权重规则来计算 View 应该占据的空间。但在很多情况下,如果给 View 设置了 match_parent 的属性,那么在计算权重时则不是通常的正比,而是反比。也就是说,权重值大的反而占据空间小)。
对于所有的 View 默认的权重是 0,如果只设置了一个 View 的权重大于 0,则该 View 将占据除去别的 View 本身占据的空间的所有剩余空间。因此这里设置 EditText 的权重为 1,使其能够占据除了按钮之外的所有空间。
让输入框充满整个屏幕的宽度
为让 EditText 充满剩余空间,做如下操作:
在
content_my.xml文件里,设置 [<EditText>] 的layout_weight属性值为1。设置 [<EditText>] 的
layout_width值为0dp。
res/layout/content_my.xml
<EditText
android:layout_weight="1"
android:layout_width="0dp"
... />
为了提升布局的效率,在设置权重时,应该把 EditText 的宽度设为 0dp。如果设置宽度为 "wrap_content",系统需要计算这个部件所占用的宽度;而此时的 EditText 因为设置了权重,所以会占据剩余空间;所以,最终导致的结果是:EditText 的宽度成了不起作用的属性。
设置 EditText 权重后的效果如图 3:

图 3 因 EditText 窗体小组件被设置了全部权重,所以占据了 LinearLayout 的剩余空间。
现在看一下完整的布局文件内容:
res/layout/content_my.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:showIn="@layout/activity_my">
<EditText android:id="@+id/edit_message"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:hint="@string/edit_message" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/button_send" />
</LinearLayout>
运行应用
整个布局默认被应用于创建项目的时候 SDK 工具自动生成的 Activity,运行看下效果:
在 Android Studio 里,点击工具栏里的 Run 按钮
。或者使用命令行,进入你项目的根目录直接执行:
$ ant debug
adb install -r app/build/outputs/apk/app-debug.apk
下一小节将学习有关如何对按钮做出相应,同时读取文本中的内容,启动另外一个 Activity 等。
3) 十分钟学会android--建立第一个APP,建立简单的用户界面的更多相关文章
- 1) 十分钟学会android--建立第一个APP,创建android项目
一个Android项目包含了所有构成Android应用的源代码文件. 本小节介绍如何使用Android Studio或者是SDK Tools中的命令行来创建一个新的项目. Note:在此之前,我们应该 ...
- 4) 十分钟学会android--建立第一个APP,启动另一个Activity
在完成上一课(建立简单的用户界面)后,我们已经拥有了显示一个activity(一个界面)的app(应用),该activity包含了一个文本字段和一个按钮.在这节课中,我们将添加一些新的代码到MyAct ...
- 2) 十分钟学会android--建立第一个APP,执行Android程序
通过上一节课创建了一个Android的Hello World项目,项目默认包含一系列源文件,它让我们可以立即运行应用程序. 如何运行Android应用取决于两件事情:是否有一个Android设备和是否 ...
- PHP学习过程_Symfony_(3)_整理_十分钟学会Symfony
这篇文章主要介绍了Symfony学习十分钟入门教程,详细介绍了Symfony的安装配置,项目初始化,建立Bundle,设计实体,添加约束,增删改查等基本操作技巧,需要的朋友可以参考下 (此文章已被多人 ...
- 十分钟学会 tmux
tmux 是一款终端复用命令行工具,一般用于 Terminal 的窗口管理.在 macOS 下,使用 iTerm2 能应付绝大多数窗口管理的需求. 如上图所示,iTerm2 能新建多个标签页(快捷键 ...
- 快速入门:十分钟学会Python
初试牛刀 假设你希望学习Python这门语言,却苦于找不到一个简短而全面的入门教程.那么本教程将花费十分钟的时间带你走入Python的大门.本文的内容介于教程(Toturial)和速查手册(Cheat ...
- Python十分钟学会
初试牛刀 假设你希望学习Python这门语言,却苦于找不到一个简短而全面的入门教程.那么本教程将花费十分钟的时间带你走入Python的大门.本文的内容介于教程(Toturial)和速查手册(Cheat ...
- 快速入门:十分钟学会Python(转)
初试牛刀 假设你希望学习Python这门语言,却苦于找不到一个简短而全面的入门教程.那么本教程将花费十分钟的时间带你走入Python的大门.本文的内容介于教程(Toturial)和速查手册(Cheat ...
- 11) 十分钟学会android--Intent消息处理与传递详解
一个Android app通常都会有多个activities. 每个activity的界面都扮演者用户接口的角色,允许用户执行一些特定任务(例如查看地图或者是开始拍照等).为了让用户能够从一个acti ...
随机推荐
- 前端面试题总结 -vue
1.active-class是哪个组件的属性? vue-router模块的router-link组件. 2.嵌套路由怎么定义? 在 VueRouter 的参数中使用 children 配置,这样就可以 ...
- LINUX命令行如何查看memcache运行状态
(附加)如何查看memcache服务器端版本: ./memcached -h memcache的运行状态可以方便的用 stats 命令显示. 首先用telnet 127.0.0.1 11211这样 ...
- Windows server 2008R2系统登录密码破解
服务器密码忘记,或者被恶意修改,系统被入侵,都是很让人烦心的事情,我试过很多方法,包括使用PE工具删除C盘Windows\System\config里面的SAM文件,可是过程都相当华美,结果都相当杯具 ...
- BZOJ 1577: [Usaco2009 Feb]庙会捷运Fair Shuttle 线段树 + 贪心
escription 公交车一共经过N(1<=N<=20000)个站点,从站点1一直驶到站点N.K(1<=K<=50000)群奶牛希望搭乘这辆公交车.第i群牛一共有Mi(1&l ...
- hadoop中的job.setOutputKeyClass与job.setMapOutputKeyClass
初学mr时,觉得没什么,但是学了一段时间,重新复习时发现程序中mr程序中一般都会有 hadoop中的job.setOutputKeyClass(theClass)与job.setOutputValue ...
- 15.6.1 【Task使用】基于任务的异步模式
C# 5异步函数特性的一大好处是,它为异步提供了一致的方案.但如果在命名异步方法以及 触发异常等方面做法存在着差异,则很容易破坏这种一致性.微软因此发布了基于任务的异步模 式(Task-based A ...
- GDB调试工具、动态加载、内存管理(day04)
一.程序中的错误处理 在系统中定义了一个全局变量errno.在这个全局变量中存放着系统调用或者库函数出错的信息(错误编号).然后根据错误编号获取错误信息. 举例说明: 打开一个文件,如果这个文件不存在 ...
- apache+php连接数据库
######## 安装APACHE ##############安装apr/usr/src/apache+php/tar xf apr-1.5.2.tar.gzcd apr-1.5.2./config ...
- 无法启用internet连接共享,为LAN连接配置的IP地址需要使用自动IP寻址
热点不能用了,一直都不知道为什么,今天查了一些资料,终于知道了原因,是因为我安装了VMware Workstation Pro ,它生成了VMnet1和VMnet8所在的两个网段,这个网段就和热点共享 ...
- 通过fmt标签格式化el表达式中的日期、小数
首先引入fmt外部文件包 <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" % ...