大家好!我是近视的脚踏实地,这篇文章主要是介绍Andriod开发布局的实验
唯有行动 才能解除你所有的不安
Android的六大基本布局分别是:①相对布局(RelativeLayout)
,②线性布局(LinearLayout)
、③表格布局(TableLayout)、④帧布局(FrameLayout)、⑤网格布局(GridLayout),@绝对布局(AbsoluteLayout)
其中,表格布局是线性布局的子类;网格布局是Android 4.0后新增的布局;而绝对布局已经淘汰,这里不做讲解。在介绍这几种布局之前,先来了解一下通用属性。
常用布局中有一些通用的属性,这些属性在任何一种布局中使用方法基本相同。
● android:id: 为控件指定相应的ID.
● android:layout width: 定义本元素的宽度。(必须要有)
● android:layout height: 定义本元素的高度。(必须要有)
● android:background: 指定该控件所使用的背景色,采用RGB命名法。
● android:orientation: 取值为horizontal表示控件水平显示(默认值),取值为vertical表示控件垂直显示。
● android:gravity: 是对view内容的限定。例如一个button上的text,你可以设置该text在view的靠左、靠右等位置。以button为例,android:gravity-"right"则表示button上的文字靠右放置。
● android-layout gravity: 用来设置view相对于父view的位置。例如一个button在linearlayout中,若想把该button放在靠左、靠右等位置,就可以通过该属性设置。以button为例
android:layout gravity="right"则表示button靠右放置。
除此之外,外间距和内间距的相关属性介绍如下。
外间距是指控件与控件间的距离
,其相关属性及解释见下表:
属性 | 解释 |
---|---|
android:layout_margin | 本元素离父容器上下、左右间的距离 |
android:layout_marginBottom | 与父容器下边缘的距离 |
android:layout_marginLeft | 与父容器左边缘的距离 |
android:layout_marginRight | 与父容器右边缘的距离 |
android:layout_marginTop | 与父容器上边缘的距离 |
android:layout_marginStart | 本元素离开始位置的距离(相当于父容器左边缘的距离) |
android:layout_marginEnd | 本元素离结束位置的距离(相当于父容器右边缘的距离) |
内间距是指控件内的内容与该控件的距离间
,其相关属性及解释见下表:
属性 | 解释 |
---|---|
android:padding | 指定布局与子布局的间距 |
android:paddingLeft | 指定布局左边与子布局的间距 |
android:paddingTop | 指定布局上边与子布局的问距 |
android:paddingRight | 指定布局右边与子布局的间距 |
android:paddingBottom | 指定布局下边与子布局的间距 |
android:paddingStart | 指定布局左边与子布局的间距(与android:paddingLeft解释相同) |
android:paddingEnd | 指定布局右边与子布局的间距(与android:paddingRight解释相同) |
相对布局(RelativeLayout) 在实际开发中是用得比较多的布局之一。相对,顾名思义是有参照的,是以某个兄弟组件或者父容器来决定的(兄弟组件是指在同一个布局里面的组件,如果是布局里一个组件参照另一个布局里的组件会出错)。
相对布局中有以下三类属性。
第一类参考容器边界(父容器),如下表:
属性 | 解释 |
---|---|
android:layout_alighParentLeft | 参考父容器左侧对齐 |
android:layout_alighParentRight | 参考父容器右侧对齐 |
android:layout_alighParentTop | 参考父容器顶端对齐 |
android:layout_alighParentBottom | 参考父容器底部对齐 |
android:layout centerHorizontal | 在父容器中水平居中 |
android:layout_centerVertical | 在父容器中垂直居中 |
android:layout_centerinParent | 在父容器中央位置 |
第二类参考兄弟控件边界,见下表:
属性 | 解释 |
---|---|
android:layout_toLeftOf | 参考兄弟控件左边界对齐 |
android:layout_toRightOt | 参考兄弟控件右边界对齐 |
android:layout_above | 参考兄弟控件上边界对齐 |
android:layout_below | 参考兄弟控件下边界对齐 |
第三类参考兄弟控件与其对齐,见下表:
属性 | 解释 |
---|---|
android:layout_alignTop | 对齐指定控件上边 |
android:layout_alignBottom | 对齐指定控件下边 |
android:layout_alignLeft | 对齐指定控件左边 |
android:layout_alignRight | 对齐指定控件右边 |
android:layout_alignBaseLine | 对齐指定控件基线 |
下面通过一个实例演示如何使用相对布局,具体操作步骤如下。
步骤1: 新建模块并命名为RelativeLayout,切换到该模块,打开res-layout目录,如下图:
步骤2: 新创建的模块默认布局为约束布局,因此需手动修改布局文件的根标签为
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
tools:context=".MainActivity">
</RelativeLayout>
(属性前面带android,意思就是该属性名称来源于androidSDK的命名空间。
在编写xml的时候,如果我们想让一个控件布满父容器,可以将layout_width和layout_height的值设置为fill_parent或者是match_parent,在高一点的版本中,谷歌建议为后者,其实我们看到很多应用都还是用的前者,或者是两者混用。其实在最终结果上这两个没有任何区别,他们的区别在于字面意义上,其实从fill_parent的实际效果来看,fill_parent(充满整个容器)这个意思是不准确的,对一个控件使用fill_parent并不总是能使其充满整个容器。
fill_parent应该是子view会占据剩下容器的空间,而不会覆盖前面已布局好的其他view空间,也就是说在前面已经有个view的空间已经分配好(最明显的情况是android:layout_width="30dip"这类),前面这个view是不会被后面fill_parent的view覆盖的,当然后面布局子 view就没有空间给分配了,所以fill_parent属性对布局顺序很重要。所以谷歌把fill_parent改成了与实际效果更符合的match_parent,表示塞满容器,塞的意思就是有多少空间,占用多少空间。)
步骤3: 在
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:text="按钮1"/>
(“wrap_content” 表示自适应大小,强制性地使视图扩展以便显示其全部内容。布局元素将根据内容更改大小,即会根据容器内的东西来决定组件的大小,例如设置一个按钮,按钮中字的多少决定了该按钮的大小)
步骤4: 创建第二个按钮,将其放于父布局的顶端且水平居中。具体代码如下:
<Button
android:id="@+id/btn2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:text="按钮2"/>
( android:id。为控件指定相应的ID,这里有两种表示方法。@id
是引用已经存在的控件, 而@+id
则是声明一个新的id.
原理:@+id
会在R.java file里面添加一个新的id,这也就是能用findViewById(R.id.xxx)找到控件的原因,而@id
就直接在这个文件里查找了。
但是如果已经存在了某个id,仍然可以使用@+id。因为android能容忍重复的id存在,但不是说会出现两个相同的id,而是新的id覆盖原有的id,此时@+id不过是将id重复创建了一遍。但不建议在已存在某id的时候再在布局中使用@+id,不规范 )
步骤5: 创建第三个按钮,将其放于父布局的顶端且位于最右侧,具体代码如下:
<Button
android:id="@+id/btn3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:text="按钮3"/>
步骤6: 创建第四个按钮,将其放于父布局的最左侧且垂直居中。具体代码如下:
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:text="按钮4"/>
步骤7: 创建第五个按钮,将其放于父布局的正中间。具体代码如下:
<Button
android:id="@+id/btn5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="按钮5"/>
步骤8: 创建第六个按钮,将其放于父布局的最右侧且垂直居中。具体代码如下
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:text="按钮6"/>
步骤9: 创建第七个按钮,将其放于第三个按钮的左边,同时位于第五个按钮的上边,还要对齐第二个按钮的左边界,如果需要参考组件,需给相应的组件设置ID.具体代码如下:
<Button
android:id="@+id/btn7"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toLeftOf="@id/btn3"
android:layout_above="@id/btn5"
android:layout_alignLeft="@id/btn2"
android:layout_below="@id/btn2"
android:text="按钮7"/>
步骤10: 创建第八个按钮,将其放于第七个按钮的左侧并与该按钮的基线对齐,具体代码如下
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toLeftOf="@id/btn7"
android:layout_alignBaseline="@id/btn7"
android:text="按钮8"/>
线性布局(LinearLayout)是程序中常见的布局方式之一,可以分为水平线性布局和垂直线性布局两种,它们分别是通过android:orientation="horizontal"和android:orientation=“vertical"来控制的。
线性布局中有以下几个极其重要的属性,直接决定元素的布局和位置。
● android:layout_gravity: 是本元素相对于父元素的对齐方式。
● android:gravity=“bottomlight”: 是本元素所有子元素的对齐方式,设置在父元素上,多个值用”|"隔开。
● android:orientation: 线性布局以列或行来显示内部子元素。
当android:orientation="vertical"时,只有水平方向的设置才起作用,垂直方向的设置不起作用,即left、right和center_horizontal是生效的.
当android:orientation="horizontal"时,只有垂直方向的设置才起作用,水平直方向的设置不起作用,即top、right和center_vertical是生效的。
● android:padding-“10dp”: 是本元素所有子元素与父元素边缘的距离,设置在父元素上.
● android:layout marginLeft-“10dp”: 子元素与父元素边缘的距离,设置在子元素上
● android:layout_weight=“1”: 分配权重值,如果垂直方向设置权重,高度应设置为0.
通过一个具体实例演示如何使用线性布局,具体操作步骤如下:
步骤1: 新建模块并命名为
<?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"
tools:context=".MainActivity">
</LinearLayout>
步骤2 : 将布局设置为修改布局属性,将其设置为垂直线性布局,并创建两个按钮控件,分别设置第一个按钮权重为“1"、第二个按钮权重为"2"。具体代码如下:
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="按钮1"
android:layout_weight="1"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="按钮2"
android:layout_weight="2"/>
步骤3 : 运行程序后查看效果,发现按钮2的权重并没有按照预定进行分配,如下图
步骤4: 水平方向设置权重后,没有按照预定的方式来设置,得到结果不正确(由于宽度是自适应的,因此与权重设置冲突后会得到一个错误的结果),要想得到正确的结果,可以将宽度设置为0dp,具体代码如下:
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="按钮1"
android:layout_weight="1"/>
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="按钮2"
android:layout_weight="2"/>
步骤5: 再次运行程序后查看效果,如下图所示。此时的权重分配是正确的,即按钮1占用1个权重、按钮2占用两个权重.
表格布局(TableLayout)继承自LinearLayout,本质是一个垂直线性布局
表格布局有以下几个重要属性
● android:stretchColumns: 拉伸列,具体通过设置列标进行拉伸。例如,设置为0拉伸第1列,设置为0、3分别拉伸第1列和第4列两列,设置为2、3、4分别拉伸第3至第5列三列,不设置则每一列都是自适应大小。
● android:shrinkColumns: 设置可收缩的列(当该列子控件内的内容太多,行内显示不完时会向列的方显示内容)
● android:collapseColumns: 设置要隐藏的列。
● android:layout_column: 指定该单元格在第几列显示
● android:layout_span: 指定该单元格占据的列数(如果使用时没有指定,那么默认值为1)
例如:
Android:layout_column=“1”,该控件在第1列
Android:layout_span=“2”,该控件占了两列
TableRow:表格中的行,所有控件都存放于TableRow中,宽度、高度可以不用设置自适应。继承自LinearLayout,本质是一个水平线性布局。
通过一个实例演示如何使用表格布局,具体操作步骤如下。
步骤1: 新建模块并命名为TableLayout,这里采用线性布局嵌套表格布局,第一个表格布局演示行伸缩性。具体代码如下:
<!-- 第1个TableLayout,用于描述表中的列属性。第0列可伸展,第1列可收缩 ,第2列被隐藏-->
<TextView
android:text="第一个表格:全局设置:列属性设置"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:textSize="15sp"
android:background="#7f00ffff"/>
<TableLayout
android:id="@+id/table1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:stretchColumns="0"
android:shrinkColumns="1"
android:collapseColumns="2"
android:padding="3dip">
<TableRow>
<Button android:text="该列可以伸展"/>
<Button android:text="该列可以收缩"/>
<Button android:text="被隐藏了"/>
</TableRow>
<TableRow>
<TextView android:text="向行方向伸展,可以伸展很长 "/>
<TextView android:text="向列方向收缩,*****************************************************************************************可以伸缩很长"/>
</TableRow>
</TableLayout>
步骤2: 第二个表格布局演示单元格属性设置。具体代码如下:
<!-- 第2个TableLayout,用于描述表中单元格的属性,包括:android:layout_column 及android:layout_span-->
<TextView
android:text="第二个:单元格设置:指定单元格属性设置"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:textSize="15sp"
android:background="#7f00ffff"/>
<TableLayout
android:id="@+id/table2"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="3dip">
<TableRow>
<Button android:text="第1列"/>
<Button android:text="第2列"/>
<Button android:text="第3列"/>
</TableRow>
<TableRow>
<TextView android:text="指定在第2列" android:layout_column="1"/>
</TableRow>
<TableRow>
<TextView
android:text="第二列和第三列!!!!!!!!!!!!"
android:layout_column="1"
android:layout_span="2"
/>
</TableRow>
</TableLayout>
步骤3: 第三个表格布局演示控件长度的可伸展特性。具体代码如下:
<!-- 第3个TableLayout,使用可伸展特性布局-->
<TextView
android:text="第三个表格:非均匀布局,控件长度根据内容伸缩"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:textSize="15sp"
android:background="#7f00ffff"/>
<TableLayout
android:id="@+id/table3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:stretchColumns="*"
android:padding="3dip"
>
<TableRow>
<Button android:text="三更灯火五更鸡" ></Button>
<Button android:text="劝学"></Button>
<Button android:text="正式少年读书时" ></Button>
</TableRow>
</TableLayout>
步骤4: 第四个表格布局演示可伸展特性及指定每个控件的宽度一致。具体代码如下
<!-- 第4个TableLayout,使用可伸展特性,并指定每个控件宽度一致,如1dip-->
<TextView
android:text="表四个表格:均匀布局,控件宽度一致"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:textSize="15sp"
android:background="#7f00ffff"/>
<TableLayout
android:id="@+id/table4"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:stretchColumns="*"
android:padding="3dip">
<TableRow>
<Button android:text="天天" android:layout_width="1dip"></Button>
<Button android:text="向上" android:layout_width="1dip"></Button>
<Button android:text="天天向上" android:layout_width="1dip"></Button>
</TableRow>
</TableLayout>
帧布局(Frame layout)是Android六大布局中最为简单的布局之一。该布局直接在屏幕上开辟出了一块空白区域,通常只添加一个控件。当然,这个控件也可以是一个布局,如果添加多个控件,会叠加在一起。
通常用于制作一个滑动菜单时,先设计一个帧布局,将其显示在屏幕之外,需要时再将其滑入屏幕。帧布局是覆盖在其他控件之上的,因此可以实现这样的效果。
帧布局中的重力引力属性如下。
layout_gravity:组合设置top | bottom | left | right |center | center_horizontal | center_vertical这些属性。
right | center_vertical:表示右侧并垂直居中。
right | bottom:表示右下角。
其中还有一些特有的属性。
android:foreground:设置该帧布局容器的前景图像。
android:foregroundGravity:设置前景图像显示的位置。
通过这个属性可以设置背景不被其他元素遮挡,始终保持顶层显示。
通过一个实例演示如何使用帧布局,具体操作步骤如下。
步骤1: 新建模块并命名为FrameLayout,修改布局为帧布局,在界面中放置3个文本框控件并设置不同的颜色及大小。具体代码如下
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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"
tools:context=".MainActivity"
android:background="@drawable/ic_launcher_background"
android:foreground="@mipmap/ic_launcher"
android:foregroundGravity="top|left">
<TextView
android:layout_width="200dp"
android:layout_height="200dp"
android:background="#FF6143"/>
<TextView
android:layout_width="150dp"
android:layout_height="150dp"
android:background="#7BFE00"/>
<TextView
android:layout_width="100dp"
android:layout_height="100dp"
android:background="#FFFF00"/>
</FrameLayout>
步骤2: 运行程序后查看效果,发现最后放置的文本框控件显示在最上层,每一个控件都覆盖在帧布局背景上,但是前景图像并没有被覆盖,如下图所示。
网格布局(Gridl.ayout)是自Android 4.0(APl Level 14)以后引入的网格矩阵形式布局控件。它与表格布局类似,但是要比表格布局更加灵活。
GridLayout属性包括两类:第一类是本身具有的属性;第二类是子元素属性。
1、本身属性
android:alignmentMode: 当其取值设置为alignMargins时,可以使视图的外边界之间进行校准。其可以取以下值。
● alignBounds: 对齐子视图边界。
● alignMargins: 对齐子视距内容。
● android:columnCount: GridLayout的最大列数。
● android:rowCount: GridLayout的最大行数。
● android:columnOrderPreserved: 当其取值设置为true时,可以使列边界显示的顺序和列索引的顺序相同。默认值为true.
● android:useDefaultMargins: 当其取值设置为ture时,如果没有指定视图的布局参数,则告知GridLayout使用默认的边距。默认值为false.
2、子元素属性
● android:layout column: 显示该子控件的列,例如android-layout column=“0”,表示当前子控件显示在第1列:android:layout column=“1”,表示当前子控件显示在第2列。
● android:layout columnSpan: 该控件所占的列数,例如android:layoutcolumnSpan=“2”,表示当前子控件占两列。
● android:layout row: 显示该子控件的行,例如android:layout row=“0”,表示当前子控件显示在第1行;android:layout row=“1”,表示当前子控件显示在第2行。
● android:layout rowSpan: 该控件所占的行数,例如android:layout rowSpan=“2”,表示当前子控件占两行。
● android:layout column Weight: 该控件的列权重,与android:layout weight类似,例如GridLayout上有两列都设置android:layout columnWeight=“1”,则两列各占GridLayout宽度的一半。
● android:layout rowWeight: 该控件的行权重,原理同android:layout column Weight
通过一个实例演示如何使用网格布局,通过网格布局设计一个计算器键盘,具体操作步骤如下。
步骤1: 新建模块并命名为GridLayout,修改布局为网格布局。具体代码如下:
<?xml version="1.0" encoding="utf-8"?>
<GridLayout 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"
tools:context=".MainActivity"
android:columnCount="4">
<Space android:layout_columnSpan="3"/>
<Button android:text="C"/>
<Button android:text="7"/>
<Button android:text="8"/>
<Button android:text="9"/>
<Button android:text="+"/>
<Button android:text="4"/>
<Button android:text="5"/>
<Button android:text="6"/>
<Button android:text="-"/>
<Button android:text="2"/>
<Button android:text="3"/>
<Button android:text="1"/>
<Space />
<Button android:text="0"
android:layout_columnSpan="2"
android:layout_gravity="fill_horizontal"/>
<Button android:text="*"/>
<Button android:text="="
android:layout_rowSpan="2"
android:layout_gravity="fill_vertical"/>
<Button android:text="/"
android:layout_columnSpan="3"
android:layout_gravity="fill_horizontal"/>
</GridLayout>
步骤2: 查看运行结果,如下图所示。此时右下角跨行的这个按钮超出了很多,这是由于父布局默认为填满父窗口,而这个跨行的按钮设置了垂直填满,因此变成了这样。
步骤3: 修改父布局,高度自适应,并调整上、下、左、右填充。具体代码如下:
android:layout width="match_parent"
android: layout height="wrap_content"
android:padding="20dp"