我们经常用到的控件都是 View 的派生类,他们通常都是可见的。 ViewGroup 也是 View 的派生类,但 ViewGroup 通常是不可见的。
ViewGroup 的主要作用:
+ 作为 Layout 。比如 LinearLayout 、 RelativeLayout 、 FrameLayout 和 TableLayout
+ 作为 View 的容器。比如 Gallery 、 GridView 、 ImageSwitcher 、 ScrollView 、 TabHost 和 ListView
其实 Layout 也可以被认为是 View 的一种容器。
本文仅讨论 ViewGroup 作为 Layout 的常用技巧。
1. LinearLayout
LinearLayout 顾名思义就是线性布局。其子 View 对象要么以 “ 行 ” 排列,要么以 “ 列 ” 排列,这取决于其 orientation 属性是 horizontal 还是 vertical 的。
创建一个 Android Project 项目。然后在创建一个 linearlayout.xml ,使其内容如下:
<? xml version = "1.0" encoding = "utf-8" ?>
< LinearLayout
xmlns:android = "http://schemas.android.com/apk/res/android"
android:orientation = "vertical"
android:layout_width = "wrap_content"
android:layout_height = "wrap_content" >
< Button
android:id = "@+id/linearbutton01"
android:layout_width = "wrap_content"
android:layout_height = "wrap_content"
android:text = " 按钮 1"
/>
< Button
android:id = "@+id/linearbutton02"
android:layout_width = "wrap_content"
android:layout_height = "wrap_content"
android:text = " 按钮 2"
/>
< Button
android:id = "@+id/linearbutton01"
android:layout_width = "wrap_content"
android:layout_height = "wrap_content"
android:text = " 按钮 3"
/>
< Button
android:id = "@+id/linearbutton01"
android:layout_width = "wrap_content"
android:layout_height = "wrap_content"
android:text = " 按钮 4"
/>
</ LinearLayout >
将 Activity 对应的代码中的 setContentView 的参数,改为: R.layout.linearlayout ,运行后得到的结果如下:
如果将 linearlayout.xml 中的 orientation 属性值改为 ”horizontal” ,那么运行后的结果如下:
2. RelativeLayout
RelativeLayout 可以根据子 View 对象彼此之间的位置关系来显示子 View 对象。比如通过 ”above” 、 ”below” 、 ”to the left of” 、 ”to the right of” 其他的子 View 对象来定位。
创建一个布局文件 relativelayout.xml ,使其内容如下:
<? xml version = "1.0" encoding = "utf-8" ?>
< RelativeLayout
xmlns:android = "http://schemas.android.com/apk/res/android"
android:id = "@+id/relativelayout"
android:layout_width = "fill_parent"
android:layout_height = "fill_parent" >
< Button
android:id = "@+id/buttonCenter"
android:layout_width = "wrap_content"
android:layout_height = "wrap_content"
android:text = "Center"
android:layout_centerInParent = "true"
/>
< ImageView
android:id = "@+id/ImageView01"
android:layout_width = "wrap_content"
android:layout_height = "wrap_content"
android:layout_above = "@id/buttonCenter"
android:layout_centerHorizontal = "true"
android:src = "@drawable/icon"
/>
< TextView
android:id = "@+id/textview01"
android:layout_width = "wrap_content"
android:layout_height = "wrap_content"
android:layout_toLeftOf = "@id/buttonCenter"
android:textSize = "20px"
android:text = "Android1"
/>
< TextView
android:id = "@+id/textview02"
android:layout_width = "wrap_content"
android:layout_height = "wrap_content"
android:layout_toLeftOf = "@id/buttonCenter"
android:layout_centerVertical = "true"
android:textSize = "20px"
android:text = "Android2"
/>
< TextView
android:id = "@+id/textview03"
android:layout_width = "wrap_content"
android:layout_height = "wrap_content"
android:layout_below = "@+id/textview01"
android:textSize = "20px"
android:text = "Android3"
/>
</ RelativeLayout >
将 Activity 对应的代码中的 setContentView 的参数,改为: R.layout.framelayout ,运行后得到的结果如下:
3. FrameLayout
FrameLayout 以 “ 栈 ” 的形式显示子 View( 比如控件 ) 。可以想 FrameLayout 添加多个 View 对象,但是每个 View 在缺省的情况下都被画在该 layout 的左上角。比如,通常可以用于在同一个区域,显示多个图片。
FrameLayout 的大小就是其中尺寸最大的子 View 的大小。
往项目的 res/drawable-mdpi 文件夹,加入两个图片资源:
它们的文件名分别为: china.png 和 macau.png 。
创建一个布局文件 framelayout.xml ,使其内容如下:
<? xml version = "1.0" encoding = "utf-8" ?>
< FrameLayout
android:id = "@+id/framelayout"
xmlns:android = "http://schemas.android.com/apk/res/android"
android:layout_width = "wrap_content"
android:layout_height = "wrap_content"
>
< ImageView
android:id = "@+id/imageview01"
android:layout_width = "wrap_content"
android:layout_height = "wrap_content"
android:src = "@drawable/china"
android:minHeight = "200px"
android:minWidth = "200px"
/>
< ImageView
android:id = "@+id/imageview02"
android:layout_width = "wrap_content"
android:layout_height = "wrap_content"
android:src = "@drawable/macau"
android:minHeight = "100px"
android:minWidth = "100px"
android:layout_gravity = "center"
/>
</ FrameLayout >
将 Activity 对应的代码中的 setContentView 的参数,改为: R.layout.framelayout ,运行后得到的结果如下:
如果把 framelayout.xml 中的第二个 ImageView 中的 android:layout_gravity="center" 属性去掉,那么所得到的结果将是:
如果将 android:layout_gravity="center" 属性加入到 FrameLayout 本身,那么得到的结果如下:
在代码中,我们可以通过形如:
FrameLayout fl = (FrameLayout)this .findViewById(R.id.framelayout );
这样的方式,来获得 FrameLayout 对象,然后通过 FrameLayout 中的方法 addView 向其中增加子 View 对象,也可以通过 removeView 从其中删除子 View 对象。 addView 和 removeView 均有多个重载方法。
4. TableLayout
TableLayout 将子 View 按照 TableRow 的方式从上到下进行排列。 TableRow 基本上和一个 orientation 属性为 “horizontal” 的 LinearLayout 相同,它代表的是一个 TableLayout 中的一行。在 TableRow 中可以增加子 View ,在用一个 TableRow 中子 View 的排列是从左至右的。
缺省地, TableRow 的顺序是从 0 开始的,在一个 TableRow 中的列的顺序也是从 0 开始的。
创建一个 tablelayout.xml ,使其内容如下:
<? xml version = "1.0" encoding = "utf-8" ?>
< TableLayout xmlns:android = "http://schemas.android.com/apk/res/android"
android:id = "@+id/talbelayout"
android:layout_width = "fill_parent"
android:layout_height = "fill_parent"
android:stretchColumns = "*"
>
<!-- * 代表所有的列 , 也可以用 "0,1,2,3,4..." 代替 -->
< TableRow android:id = "@+id/tablerow0" >
< TextView
android:text = "1234567890"
android:textSize = "10px"
/>
< TextView
android:text = "1234567890"
android:textSize = "10px"
/>
< TextView
android:text = "1234567890"
android:textSize = "10px"
/>
< TextView
android:text = "1234567890"
android:textSize = "10px"
/>
</ TableRow >
<!-- 上面的代码 , 意味着这个 TableLayout 有 4 列 -->
< TableRow android:id = "@+id/tablerow1" >
< Button
android:id = "@+id/leftbutton"
android:text = "Left"
android:textSize = "12px"
android:layout_height = "40px"
/>
< Button
android:id = "@+id/leftbutton"
android:text = "Middle"
android:textSize = "12px"
android:layout_height = "40px"
/>
< Button
android:id = "@+id/leftbutton"
android:text = "Right"
android:textSize = "12px"
android:layout_height = "40px"
android:layout_column = "2"
android:layout_span = "2"
/>
</ TableRow >
<!-- leftbutton 的起始位置在第 2(3) 列 (android:layout_column="2") ,
占用 2 列 (android:layout_span="2") -->
< TableRow android:id = "@+id/tablerow2" >
< Button
android:id = "@+id/backbutton"
android:text = "Back Button"
android:layout_column = "2"
/>
</ TableRow >
<!-- backbutton 处于第 2(3) 列的位置 (android:layout_column="2")-->
< TableRow android:id = "@+id/tablerow3" >
< Button
android:id = "@+id/spanbutton"
android:text = "Span Button"
android:layout_column = "0"
android:layout_span = "2"
/>
</ TableRow >
<!-- backbutton 处于第 0(1) 列的位置 (android:layout_column="0")
占用 2 列 (android:layout_span="2")-->
< TableRow android:id = "@+id/tablerow4" >
< TextView
android:gravity = "right"
android:paddingRight = "8px"
android:text = " 姓名 : "
/>
< EditText
android:id = "@+id/editname"
android:layout_column = "1"
android:layout_span = "2"
android:text = ""
/>
</ TableRow >
< TableRow android:id = "@+id/tablerow5" >
< TextView
android:gravity = "right"
android:paddingRight = "8px"
android:text = " 地址 : "
/>
< EditText
android:id = "@+id/editname"
android:layout_column = "1"
android:layout_span = "3"
android:text = ""
/>
</ TableRow >
</ TableLayout >
将 Activity 对应的代码中的 setContentView 的参数,改为: R.layout.tableayout ,运行后得到的结果如下: