Building a Simple User Interface(创建一个简单的用户界面)

时间:2021-07-01 17:03:01

  对于一个android 应用程序,用户的图形界面通常是由View(视图)和ViewGroup(视图组)对象构成的层次结构。 View(视图)对象通常是按钮或文本输入框这类UI小部件,ViewGroup(视图组)对象是一些用来定义子视图布局的不可见容器,就像一个grid(表格)或者vertical List(垂直列表)。

  Android提供了对应于View和ViewGroup对象的子类的XML 标签,所以你可以在XML文件中按照层次结构定义你的UI组件

  Building a Simple User Interface(创建一个简单的用户界面)

  图 1. ViewGroup(视图组)对象以及其包含的View (对象)的分支图

  在这节课中,你将创建一个包含了一个文本框以及一个按钮的XML布局文件。

  在接下来的课程中,当按钮被按下时,将会对此作出响应,发送文本框中的内容到另一个activity

  

 创建一个Linear Layout(线性布局)

  打开 res/layout/ 文件夹下的 activity_main.xml  文件

  注意:在Eclipse中,当你打开一个布局文件,第一次显示的是图形布局编辑器,这是一个可以帮助你构建布局的所见即所得的编辑器。

  在这课中,你将会直接使用xml文件,所以点击窗口下方的 activity_main.xml 选项来打开XML编辑器。

   

  在你创建项目的时候你选择的BlankActivity模板将会在 activity_main.xml 文件中创建一个RelativeLayout的根标签,

  首先,我们删除<TextView>标签元素,同时把<RelativeLayout>标签元素修改为<LinearLayout>,接着给它添加一个android:orientation属性,设置它的值为"horizontal"。

  代码如下:

  

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
    android:orientation="horizontal" >
</LinearLayout>

LinearLayout 是一个视图组(ViewGroup对象的子类),它通过指定android:orientation属性类横向或者纵向地布局他的子类视图,屏幕上的每一个子类视图都会按照xml文件中的顺序进行

展现。

另外的两个属性,android:layout_widthandroid:layout_height,用来指定视图的大小尺寸,

因为LinearLayout是布局文件中的根元素,所以为了让它填满整个屏幕区域,我们需要设置它的宽和高为“matchparent”,

这个属性将会让它扩展自己的宽度和高度来匹配父视图。

如果想了解更多的布局属性,可以查看Layout指导

 

添加一个文本域

   要创建一个用户可编辑的文本域,我们在<LinearLayout>标签内加入一个<EditText>元素,

跟每一个视图对象一样,你必须定义指定的xml属性来指定EditText对象的属性,

这里是你如何在<LinearLayout>元素标签中定义EditText的属性:

  

 <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 tools会使用这个id名称在你项目中的gen/R.java 下创建一个新的资源ID来关联你的EditText  元素。一旦资源id使用这种方式被定义了,其他关联该资源的定义就不用再使用加号了。只有当你指定一个新的资源ID而不是具体的资源时,才需要使用加号,

  

  android:layout_width a和 android:layout_height

  除了使用指定的宽度跟高度外,属性中“wrap_content”会自动匹配视图内容的大小来进行展示,如果你使用“match_parent”,那么EditText会填充整个屏幕,因为它会匹配父组件LinearLayout 的宽高,更多的信息可以查看Layouts 指导。

  

  android:hint

  这个属性用来给空文本域设置一个默认值。除了使用硬编码的方式定义它的值,我们还可以通过“@string/edit_message”这种方式关联一个指定的字符串资源文件,

因为它关联的是一个具体的资源,所以不需要在前面加加号,不过因为你还没有定义字符串资源文件,所以你将会看到一个编译错误,我们将会在下一章节修复这个问题

 

注意: 这个字符串跟元素ID有着相同的名称:edit_message.不过,资源文件的作用域范围是跟资源类型关联的(例如id或者string),所以使用相同的名称不会引起冲突

 

添加字符串资源

  当你需要添加文本到你的用户界面时,你应该始终将你的字符串作为资源来指定。字符串资源允许你在一个单独的位置管理所有UI界面的文本,可以让你更快更方便地找到和修改文本,

外部化的字符串还可以通过为不同的语言做不同的定义来实现本地化的功能。

  一般默认情况下,你的android项目在res/values/strings.xml 下包含了字符串资源,我们来添加一个name为”edit_message“的字符串,然后设置它的值为”Enter a message“(你可以删除”hello_world“字符串,不影响我们的项目)。

  与此同时,我们为按钮添加一个名为”send“的字符串,内容为”button_send“.

  这时string.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>
    <string name="title_activity_main">MainActivity</string>
</resources>

要了解更多的关于通过资源文件配置实现语言本地化的功能, 可以查看 Supporting Different Devices(多设备支持) 课程.

 

添加一个按钮

  现在我们在布局中添加一个按钮,紧接着<EditText>标签元素我们添加一个<Button> 标签:

  

  <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/button_send" />

  这里的宽高被设置成了”wrap_content“,那么这个按钮的宽高只会匹配它的文本内容的宽高,因为我们不会在activity的代码中关联按钮,所以我们在这里没有给按钮设置android:id属性。

  

设置输入框宽度填满屏幕

  当前的布局的定义使得 EditText 和 Button 组件的宽高和它的内容匹配,如图2所示: 

    Building a Simple User Interface(创建一个简单的用户界面)

  图2. EditText 和 Button 组件的宽度被设置为了"wrap_content".

  这样的宽度设置对button按钮来说不错,但是对于textfield文本框来说,并不是很好,用户如果在其中输入内容将会让文本框宽。

所以,最好的方案是让文本框填充未使用的屏幕宽度空间,你可以在LinearLayout中设置 android:layout_weight 属性来达到这一要求。

  权重值(weight)是一个用来指定视图组件占比的数值,例如,你给一个视图对象(view)设置了权重值为2,另一个设置了权重值为2,那么总的权重值是3,

所以,第一个视图对象会填充2/3的剩余空间,而第二个视图会填充剩下的空间,如果你再添加第三个视图对象,并给他设置一个权重值1,那么第一个视图将占用1/2的剩余空间,

剩下的两个视图分别占用1/4.

  所有视图的默认权重值都是0, 所以如果你给一个视图指定一个大于0的任意权重值,并且只有它一个视图组件被指定了权重值,那么它将填充剩下的它所需要的所有空间,

所以,为了让EditText能够填充剩下的空间,我们给它添加权重值为1,并且不给button组件添加权重值

  

<EditText
        android:layout_weight="1"
        ... />

  为了提高布局的效率,当你指定权重值时,你应该修改EditText的宽度为0(0dp)。设置宽度为0,会提高布局的性能,

因为使用"wrap_content"属性设置宽度时需要系统进行一次无关紧要的计算,因为宽度值需要另一个计算来填充剩余空间。

<EditText
        android:layout_weight="1"
        android:layout_width="0dp"
        ... />

图3为展示效果

Building a Simple User Interface(创建一个简单的用户界面)

图3. EditText拥有所有的权重, 所以它填充了 LinearLayout剩下的所有空间.

下面是完成的布局代码:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
    android:orientation="horizontal">
    <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>

我们可以运行下程序看下效果

 

下一课我们将继续学习如何响应一个按钮的按下动作,从文本域读取内容,启动另一个视图组件,以及一些其他知识

 

 

 

 

 

  

 

  翻译中...