实战Android编程——手把手教你做出商用软件
34
第3章Android布局管理器本章要介绍的内容为Android平台下的布局管理器。Android中的布局包括线性布局、表
格布局、相对布局、帧布局和绝对布局。下面将分别对每个布局管理器进行详细的介绍。
3.1 控件类概述
3.1.1  View类简介
在介绍Android的布局管理器之前,有必要让读者了解Android平台下的控件类。首先要了解的是View类,该类为所有可视化控件的基类,主要提供了控件绘制和事件处理的方法。创建用户界面所使用的控件都继承自View,如TextView、Button、CheckBox等。
关于View及其子类的相关属性,既可以在布局XML文件中进行设置,也可以通过成员方法在代码中动态设置。View类常用的属性及其对应方法如表3-1所示。
表3-1  View类常用属性及对应方法说明
属性名称对应方法描述
android:background setBackgroundResource(int) 设置背景
android:clickable setClickable(boolean) 设置View是否响应点击事件
android:visibility setVisibility(int) 控制View的可见性
android:focusable setFocusable(boolean) 控制View是否可以获取焦点
android:id setId(int) 为View设置标识符,可通过findViewById方法获取android:longClickable setLongClickable(boolean) 设置View是否响应长点击事件
android:soundEffectsEnabled setSoundEffectsEnabled(boolean) 设置当View触发点击等事件时是否播放音效
android:saveEnabled setSaveEnabled(boolean) 如果未作设置,当View被冻结时将不会保存其状态
android:nextFocusDown setNextFocusDownId(int)
定义当向下搜索时应该获取焦点的View,如果该View 不存在或不可见,则会抛出RuntimeException异常
android:nextFocusLeft setNextFocusLeftId(int) 定义当向左搜索时应该获取焦点的View
android:nextFocusRight setNextFocusRightId(int) 定义当向右搜索时应该获取焦点的View
续表属性名称对应方法描述
android:nextFocusUp setNextFocusUpId(int) 定义当向上搜索时应该获取焦点的View,如果该View
第3章  Android 布局管理器
3
5不存在或不可见,则会抛出RuntimeException 异常
说明:任何继承自View 的子类都将拥有View 类的以上属性及对应方法。
3.1.2  ViewGroup 类简介
另外一个需要了解的是ViewGroup 类,它也是View 类的子类,但是可以充当其他控件的容器。ViewGroup 的子控件既可以是普通的View ,也可以是ViewGroup ,实际上,这是使用了Composite 的设计模式。Android 中的一些高级控件如Galley 、GridView 等都继承自ViewGroup 。
与Java SE 不同,Android 中并没有设计布局管理器,而
是为每种不同的布局提供了一个ViewGroup 的子类,常用的
布局及其类结构如图3-1所示。
3.2  线性布局 本节将会对线性布局进行简单的介绍。首先向读者介绍LinearLayout 类的相关知识,然后通过一个实例说明LinearLayout 的用法。
3.2.1  LinearLayout 类简介
线性布局是最简单的布局之一,它提供了控件水平或者垂直排列的模型。同时,使用此布局时可以通过设置控件的weight 参数控制各个控件在容器中的相对大小。LinearLayout 布局的属性既可以在布局文件(XML )中设置,也可以通过成员方法进行设置。表3-2给出了LinearLayout 常用的属性及这些属性的对应设置方法。
表3-2  LinearLayout 常用属性及对应方法 属性名称 对应方法 描    述
android:orientation setOrientation(int) 设置线性布局的朝向,可取horizontal 和vertical 两种排列方式
android:gravity setGravity(int) 设置线性布局的内部元素的布局方式
在线性布局中可使用gravity 属性来设置控件的对齐方式,gravity 可取的值及说明如表3-3所示。
提示:当需要为gravity 设置多个值时,用“|”分隔即可。
表3-3  gravity 可取的属性及说明
属 性 值
说    明
top 不改变控件大小,对齐到容器顶部 续表
属 性 值
说    明
bottom 不改变控件大小,对齐到容器底部 图3-1  布局管理器的类结构
实战Android 编程——手把手教你做出商用软件
36 left
不改变控件大小,对齐到容器左侧
right
不改变控件大小,对齐到容器右侧 center_vertical
不改变控件大小,对齐到容器纵向中央位置 center-horizontal
不改变控件大小,对齐到容器横向中央位置 center
不改变控件大小,对齐到容器中央位置 fill_vertical
若有可能,纵向拉伸以填满容器 fill_horizontal
若有可能,横向拉伸以填满容器 fill 若有可能,纵向横向同时拉伸以填满容器
3.2.2  线性布局案例
在前面的章节中介绍了LinearLayout 类的相关知识,本节将通过一个案例来说明LinearLayout 的用法。本案例的开发步骤如下。
在Eclipse 中新建一个项目Sample_3_1,首先打开项目文件夹下res/values 目录下的l ,在其中输入如下代码。
1 <?xml version="1.0" encoding="utf-8"?>
2 <resources>
3    <string name="app_name">LinearExample</string>
4    <string name="button">按钮</string>
5    <string name="add">添加</string>
6 </resources> 代码位置:见随书光盘中源代码/第3章/Sample_3_1/res/values 目录下的l 。
说明:在l 中主要声明了程序中要用到的字符串资源,这样将所有字符串资源统一管理有助于提高程序的可读性及可维护性。
打开项目文件夹下的res/layout 目录下的l ,
将其中已有的代码替换为如下代码。 1 <?xml version="1.0" encoding="utf-8"?>
2 <LinearLayout xmlns:android="schemas.android/apk/res/android"
3  android:orientation="vertical"
4  android:layout_width="fill_parent"
5  android:layout_height="fill_parent"
6  android:id="@+id/lla"
7  android:gravity="right"
8  >    <!-- 声明一个LinearLayout 布局,并设置其属性 --> 9  <Button
10  android:text="@string/add"
11  android:id="@+id/Button01"
12  android:layout_width="wrap_content"
13  android:layout_height="wrap_content">
14  </Button>    <!-- 声明一个Button 布局,并设置其id 为Button01 --> 15 </LinearLayout>
代码位置:见随书光盘中源代码/第3章/Sample_3_1/res/layout 目录下的l 。
¾ 第2~8行声明了一个线性布局,第3行设置线性布局的朝向为垂直排列。
¾ 第4~5行设置该线性布局在其所属的父容器中的布局方式为横向和纵向填充父容器。 ¾ 第6行为该线性布局声明了ID 。第7行设置该线性布局内部元素的布置方式为向右对齐。
第3章  Android 布局管理器
3
7¾ 第9~14行声明了一个Button 控件,其ID 为Button01,第10行设置Button 控件显示的文本内容为资源文件l 中的属性值。
¾ 第12~13行设置Button 控件在父容器中的布局方式为只占据自身大小的空间。
打开项目的Activity 文件LinearActivity.java ,将其中已有的代码替换为如下的代码。 1 package wyf.jc;        //声明包语句
2 import android.app.Activity;      //引入相关类
3 import android.os.Bundle;      //引入相关类
4 import android.view.View;      //引入相关类
5 import android.widget.Button;      //引入相关类
6 import android.widget.LinearLayout;    //引入相关类
7 public class LinearActivity extends Activity {
8  int count=0;        //计数器,记录按钮个数 9    @Override
10    public void onCreate(Bundle savedInstanceState) { //重写onCreate 方法 11        Create(savedInstanceState);
12        setContentView(R.layout.main);
13        Button button = (Button) findViewById(R.id.Button01);
//获取屏幕中的按钮控件对象
14        button.setOnClickListener(  //为按钮添加OnClickListener 接口实现 15      new View.OnClickListener(){
16        public void onClick(View v){
17        LinearLayout ll=(LinearLayout)findViewById(R.id.lla);            //获取线性布局对象
18    String msg=Resources().getString(R.      string.button);
19    Button tempbutton=new Button(LinearActivity.this);            //创建一个Button 对象
20    tempbutton.setText(msg+(++count)); //设置Button 控件显示的内容 21    tempbutton.setWidth(80);  //设置Button 的宽度 22    ll.addView(tempbutton);  //向线性布局中添加View 23        }
java布局管理器24  });
25  }
26 }
代码位置:见随书光盘中源代码/第3章/Sample_3_1/src/wyf/jc 目录下的l 。
¾ 代码第8行声明了用于记录生成的按钮编号的计数器。
¾ 代码第13行通过findViewById 方法获取屏幕中的Button 控件对象。
¾ 代码第15~24行为Button 对象添加了OnClickListener 的实现。
¾
代码第17~23行为对OnClickListener 接口中onClick 方法的实现,在该方法中首先获得线性布局LinearLayout 对象的引用,然后创建一个Button 对象并调用LinearLayout 对象的addView 方法将其添加到线性布局容器中。
完成上述三个步骤的工作后,运行项目,在程序中单击“添加”按钮可向屏幕中添加新的按钮,效果图如图3-2所示。
图3-2为当LinearLayout 的orientation 属性为vertical 时的运行效果,下面来看orientation 值为horizontal 时的运行效果,将步骤中的第3行代码改为如下代码。
1 android:orientation="horizontal" 代码位置:见随书光盘中源代码/第3章/Sample_3_1/res/layout 目录下的l 。