3.2 改动Layout

让我们改一下这个Layout,显示一个图片吧。首先看一下Android Studio的界面设计器中为我们提供了哪些可用的控件,如图3.2.1所示。

图3.2.1

控件的类别有:


• Common:一些最常用的控件。

• Text:文本显示控件和各种文本输入控件,它们都不能容纳孩子。

• Buttons:各种按钮。

• Wedgets:包含各种不好分类的控件,它们的共同特点是不能容纳孩子。

• Layouts:专门用于排版的控件们,它们是容器,专用于容纳孩子们,按某种规则排列它的孩子们。

• Containers:容器,与Layout,专门于用容纳孩子们,支持内容滚动,孩子们的排列方式固定,不能更改。

• Google:Google为Android提供的第三方控件,比如Google的广告控件,Google地图控件。

• Legacy:旧控件们,有了新的替代控件。

• Project:我们在项目中自定义的控件们。


要显示图像,应该去Common或Widgets组中去找控件。如图3.2.2所示。

图3.2.2

选择“ImageView(图像视图)”这个控件,然后把它拖到了预览页面的内容区。当你放开鼠标时,Android Studio就会打开一个窗口,让你选择要在这个图像控件中显示的图像(第一次运行可能要等很长很长时间),如图3.2.3所示。

图3.2.3

最左边为类别,有“Drawable”和“Color”,分别表示图像和颜色。你要选择“Drawable”,右边显示的都是可用的图像资源(就是图片文件)。这些Drawable资源又被分为“Project”和“Android”两组,Project表示我们工程中带的资源,android表示Andriod SDK中带的资源。随你便,选什么都行,比如我选Project中的第一个:ic_launcher,点OK后就可以看到预览界面中多了一个图像,如图3.2.4所示。

图3.2.4

图像有点小,你可能想把这个图像调大一点,怎么做呢?图像控件默认是以显示的图像的真实大小来决定自身的大小,也就是控件适应图像,但也可以反过来,让图像适应控件,此时我们应该为图像控件指定固定的大小,然后让图像根据图像控件自动缩放。要做到此效果,只需要修改图像控件的“layout_width”(宽度)和“layout_height”(高度)属性。要想修改控件属性,需打开属性栏,如图3.2.5所示。

图3.2.5

红箭头所指就是属性栏开关,点它打开属性栏,如图3.2.6所示。

图3.2.6

红框内就是属性栏,你可能看到的内容跟我的不一样,是因为你当前选中的控件跟我的不一样,当你在预览窗口或控件树中选中图像控件,就看到跟我一样的内容了。

可以看到当前layout_width和layout_height的值都是“wrap_content(包着内容)”,所以控件的大小由其内容(就是图像)决定。现在让我们把这两个值改为固定的大小,比如宽和高都改为“200dp”,效果如图3.2.7所示。

图3.2.7

看到了吧?图像被我们搞大了!

有人可能注意到了表示距离的数字后要带“dp”,是的,必须带它,它是一个距离单位,表示的是实际的物理距离,与像素大小无关。

提示

属性栏中显示的属性是随着你选择的控件而变化的,你可以点“Hello World!”这个文本控件试试,是不是显示的属性变了?所以你在编辑属性之前要先确定点的是哪个控件,因为经常发生点错的情况。

要知后事如何,下节分解。

3.2.1 添加图像资源

如果我们想在图像中显示自己喜欢的图像,怎么办呢?这也不难,我们可以把电脑上的图像复制到工程的资源中,这样就可以在工程中使用它们了。

做法是这样:在你的文件浏览器中找一个图像文件(如果没有就从网上下载一个),最好是png格式的,jpg的也行,然后在文件浏览器中复制此文件(不要说你不知道怎么复制,按Ctrl+C或在右键快捷菜单中选“复制”),然后在你的工程中,在要放入的组上点右键,在右键菜单中选“Paste(粘贴)”即可,如图3.2.1.1所示。

图3.2.1.1

图像必须放到“drawable”组中。drawable组中专门放可以绘制的资源,所以你不要放到其他组中。点了粘贴(Paste)之后出现如图3.2.1.2所示的对话框。

图3.2.1.2

这个对话框给你一个修改文件名和文件存放位置的机会,存放位置没问题,不要动。资源名字你可以随便取,但要有意义,而且也不能用中文,不能以数字开头,字母不能大写,如果不符合这些要求,工程编译通不过。如果你英语不好就用拼音取名。如果你的资源文件名不符和要求,当你编译App时,就会看到错误,如图3.2.1.3所示。

图3.2.1.3

在“Messages”这个窗口中,输出了编译中遇到的错误,可以看到这个错误最后给出的原因:“The resource name must start with a letter”,意思是资源的名字必须以字母开头。

文件或文件夹改名

如果这个资源已加入了工程,但是名字不合格,怎么办呢?还是可以改名的!改名方式是这样的:在文件上点出右键菜单,选“Refactor(重构)”,再选“Rename(重命名)”,如图3.2.1.4所示。

图3.2.1.4

一个窗口现身,如图3.2.1.5所示。

图3.2.1.5

注意改名时不要改扩展名,改完后点“Refactor(重构)”即可。

既然已添加了自己的图像资源,那就把它显示出来吧?预知后事如何,下节分解。

3.2.2 显示自己的图像

选中图像控件,打开属性栏,如图3.2.2.1所示。

图3.2.2.1

在列出的属性中没有改变图像的项,不是没有,是隐藏了。默认下,属性栏中只显示少量常用的属性,要想看到全部属性,需要点箭头所指的链接“View all properties(查看所有属性)”,你会发现显示出了一大堆属性,如图3.2.2.2所示。

图3.2.2.2

拖动滚动条,就可以看到所有属性。那么,哪个是改变所显图像的属性呢?这个属性叫“srcCompat”,上图中可以看到,它的值是“@mipmap/ic_launcher”。这个以“@”开头的字符串表示的是一个ID,每个资源都有自己的ID,ID的名字就是这个资源的文件名。这里通过这个ID引用了一个图像资源。我们要改变显示的图像,可以为这个属性直接写入某个图片的ID,但是手写麻烦易出错,我们还是借助工具来设置吧,点图3.2.2.3所示的按钮。

图3.2.2.3

弹出了资源选择对话框,如图3.2.2.4所示。

图3.2.2.4

这次选“Project”区中的female图像(我们刚加入的),点OK。现在图像控件变成了这样,如图3.2.2.5所示。

图3.2.2.5

终于看到了头像!

你一定要注意!Android Studio会很自作聪明地把属性编辑器中你刚刚编辑过的属性移到靠顶的位置,就是说这些属性在属性栏中乱跑!这到底是在帮忙还是捣乱?反正搞得我很不适应。

运行起来看看真实的效果是什么样的吧?运行App的方法,请参考2.2节。

此时,activity_main.xml这个文件的内容是这样的:

这些源码是怎么看到的呢?看下面图3.2.2.7就明白了:

图3.2.2.7

3.2.3 XML小解

界面设计文件的格式是XML。虽然我作此书时假设你已知道什么是XML,但是终究会有初学者读此书,我还是把XML稍微解释一下。

XML是存储数据的一种格式,它只能以文本方式存数据,也就是说它存不了图片(也有办法存,但很麻烦,也不推荐这样做,所以你现在可以认为它只能存文本)。它的数据由元素组成,一条数据是一个元素,元素由标记来表示,标记即以“< >”包起来的文本。比如:<aaa></aaa>就是一个元素,<aaa>是元素的开始标记,</aaa>是它的结束标记。如果一个元素不包含子元素,就为空元素。比如这里<aaa>就是一个空元素。空元素可以把结束标记省略,写作:<aaa />。以下则表示<aaa>有儿子<bbb>和<ddd>,还有孙子<ccc>:

<aaa>
<bbb>
<ccc />
</bbb>
<ddd />
</aaa>

一个元素除了可以有多个儿子,还可以有多个属性,如:<aaa eee="1" />,eee就是<aaa>的一个属性,等号前是属性的名字,等号后是属性的值。注意属性的值必须用单引号或双引号包起来。

提示

引号必须是半角字符!这是一个新手常掉进去的坑。

3.2.4 Layout源码解释

现在让我们逐条解释activity_main.xml文件中一些令人迷惑的代码。

<?xml version="1.0" encoding="utf-8"?>

XML都这样开头,不要太在意。version表示版本是1.0,encoding表示编码是utf8,要想没乱码,你必须保证这个XML文件真的是utf8编码。

<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="niuedu.com.andfirststep.MainActivity">

这是界面的最外层的元素,可以看到标记名是一个类(ConstraintLayout)的全名。如果这个类是Android SDK的核心库中的类,可以把包省略,只写类名。根据类名我们就知道界面的最外面是一个ConstraintLayout控件。

此元素中有一些“xmlns”开头的属性,它为xml命名空间指定了别名,比如“android”“app”和“tools”就是三个别名,要使用那个命名空间中定义的符号,必须在名字前带上命名空间的别名,比如:android:layout_width="match_parent",这个属性名layout_width就属于android这个别名所对应的命名空间中定义的符号,如果命名空间没有引入,就不能使用。此时Android Studio会提示语法错误。比如,当我把xmlns:android="http://schemas.android.com/apk/res/android"这一条删掉之后,出现了如图3.2.4.1所示的样子。

图3.2.4.1

看到了吧?所有的“android”变成了红色(对照IDE看)。

宽和高这两个属性必须存在,即:

android:layout_width="match_parent"
android:layout_height="match_parent"

它们是控件的宽和高,这两个属性必须存在!“match_parent”的意思是匹配父控件,就是与父控件的大小一样。ConstraitLayout是最外面的控件,它的大小必须与Activity一样,也就充满整个屏幕,所以值必须为“match_parent”(我们前面讲过了,宽和高的值可以有三种:match_parent、wrap_content和固定值)。

以“tools”为前缀的属性,仅在界面设计器中起作用。这些属性都是用于设计界面时指示界面设计器的行为的,在App运行时它们是不起作用的。比如tools:context="niuedu.com.andfirststep.MainActivity",这是告诉界面设计器此Layout中定义的界面与MainActivity这个类关连,其实真正的关联是由Java代码决定的,可以与这里不一致而不影响运行。

android:id="@+id/imageView2"

这个属性是为控件设置ID。ID是一个控件的唯一标志,此处的ID叫作“imageView2”。在一个Layout文件中的ID不能重复。“imageView2”是ID的名字,ID在App运行时其实是一个整数。如果一个控件要与另一个控件发生关系,那么就是通过ID来引用另一个控件。不仅控件要有ID,所有的资源都有ID,比如我们这个layout文件activity_main.xml,它的ID的名字就是文件名activity_main。