本篇介绍android的常用布局以及工作中经常用到的属性。
Android程序布局有两种声明方式:
- 使用XML文件描述界面布局;
- 在Java代码中通过调用方法进行控制。
建议尽量采用XML文件声明界面元素布局,使用java代码动态添加界面布局会大大降低应用响应速度。常用的布局有以下7种,本文介绍常用的前3种,重点介绍ConstraintLayout。
- 线性布局(LinearLayout)
- 网格布局(GridLayout)
- 约束布局(ConstraintLayout)
- 框架布局(FrameLayout)
- 表格布局(TableLayout)
- 相对布局(RelativeLayout)
- 绝对布局(AbsoluteLayout)
线性布局(LinearLayout)
LinearLayout容器中的子元素顺次排列,横向或纵向。
常用属性 | 说明 |
---|---|
layout_width | match_parent:匹配父容器;wrap_content:包裹子元素或内容 |
layout_height | 同上 |
orientation | vertical:竖排;horizontal:横排; |
容器内子元素的常用属性:
常用属性 | 说明 |
---|---|
layout_weight | 按照layout_width/layout_height分配完空间后,对剩余空间分配的比例,默认为0 |
layout_gravity | 相对于子元素的父元素来说,设置子元素在父元素的什么位置 |
gravity | 是对子元素的view控件本身来说,设置本身内容显示在view的什么位置 |
示例
以下示例,分别演示了竖排和横排(嵌套式)线性布局。
- 按钮2 演示了gravity属性
- 按钮3演示了layout_gravity属性
- 按钮4、5、6演示了layout_weight属性
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="按钮1" />
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="按钮2"
android:gravity="right" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="按钮3-左对齐"
android:layout_gravity="left" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="按钮3-右对齐"
android:layout_gravity="right" />
<LinearLayout android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<Button
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:text="按钮4" />
<Button
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:text="按钮5"
android:layout_weight="1"/>
<Button
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:text="按钮6" />
</LinearLayout>
</LinearLayout>
网格布局(GridLayout)
GridLayout是Android4.0增加的网格布局控件,可以减少布局嵌套,它把整个容器划分为rows × columns个网格,每个网格可以放置一个组件。可认为是TableLayout的升级,布局更灵活且渲染速度也比tablelayout要快。
GridLayout 常用属性
xml常用属性 | 说明 |
---|---|
android:columnCount | 最大列数;若为0,代表列数不限; |
android:rowCount | 最大行数;若为0,代表行数不限 |
android:alignmentMode | alignBounds:对齐子视图边界 alignMargins :对齐子视距内容,默认值 |
android:columnOrderPreserved | 使列显示的顺序和列索引的顺序相同,默认是true |
android:rowOrderPreserved | 使行显示的顺序和行索引的顺序相同,默认是true |
android:useDefaultMargins | 没有指定视图的布局参数时使用默认的边距,默认值是false |
容器内子元素的常用属性:
xml常用属性 | 说明 |
---|---|
android:layout_column | 指定该单元格在第几列显示 |
android:layout_row | 指定该单元格在第几行显示 |
android:layout_columnSpan | 指定该单元格占据的列数(需要与layout_gravity配合使用) |
android:layout_rowSpan | 指定该单元格占据的行数(需要与layout_gravity配合使用) |
android:layout_gravity | 指定该单元格在容器中的位置方式 |
android:layout_columnWeight | 列宽权重(可实现横向填满容器,需要对该列全部元素都是用该属性才有效) |
android:layout_rowWeight | 行高权重(可实现纵向填满容器) |
注意
1、如果子元素都没有设置layout_column和layout_row属性,则按照设置的行数和列数,把全部组件按照从上到下从左到右的顺序,自动填充到单元格;如果对某一元素设置的layout_column和layout_row属性与它顺次得到的行列属性不一致,则以设置的layout_column和layout_row属性为准,而且后面的控件相对该控件的实际位置,进行顺次排列。
2、当子元素的数量超过 行数×列数 ,自动加行依次排列。
3、单元格属性的设置往往是互相关联、互相影响的,只对一个单元格的设置可能达不到想要的效果或者影响了其它单元格的位置。
示例
- 按钮7 演示了layout_rowSpan属性
- 按钮0演示了layout_columnSpan属性
- 按钮9641演示了layout_columnWeight属性
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:rowCount="4"
android:columnCount="3">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_columnWeight="1"
android:text="9" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="8" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_rowSpan="2"
android:layout_gravity="fill_vertical"
android:text="7" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_columnWeight="1"
android:text="6" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="5" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_columnWeight="1"
android:text="4" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="3" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="2" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_columnWeight="1"
android:text="1" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_columnSpan="2"
android:layout_gravity="fill_horizontal"
android:text="0" />
</GridLayout>
约束布局(ConstraintLayout)
从 Android Studio 2.3 起,官方的模板默认使用 ConstraintLayout。它的出现主要是为了解决布局嵌套过多的问题,以灵活的方式定位和调整小部件。可认为是RelativeLayout的升级,可以按照比例约束控件位置和尺寸,渲染速度更快。
ConstraintLayout本质上也是一种相对布局,看下面的图感受一下,每一个组件的上下左右四个方向中的两个方向都与另一个组件(也可能是父容器)有相对位置关系。
一、相对定位属性
1、上下左右
layout_constraintLeft_toLeftOf
layout_constraintLeft_toRightOf
layout_constraintRight_toLeftOf
layout_constraintRight_toRightOf
layout_constraintTop_toTopOf
layout_constraintTop_toBottomOf
layout_constraintBottom_toTopOf
layout_constraintBottom_toBottomOf
——————————————————
android:layout_marginStart
android:layout_marginEnd
android:layout_marginLeft
android:layout_marginTop
android:layout_marginRight
android:layout_marginBottom
这一类属性最常用,下面代码意思是TextView2的左边靠着TextView1的右边,距离为20dp。
android:id="@+id/TextView2"
app:layout_constraintLeft_toRightOf="@+id/TextView1"
android:layout_marginLeft="20dp"
2、文本基线
- layout_constraintBaseline_toBaselineOf
当两个TextView的高度不一致,但是又希望他们文本对齐,可如下设置。
app:layout_constraintBaseline_toBaselineOf="@+id/textView2"
3、起始
layout_constraintStart_toEndOf
layout_constraintStart_toStartOf
layout_constraintEnd_toStartOf
layout_constraintEnd_toEndOf
start、end与left、right的用法等同,官方推荐使用start、end。因为考虑到少数语言是从右向左书写的,因此用left、right可能不准确。
4、控件在ConstraintLayout里面要实现margin,必须先约束该控件在ConstraintLayout里的位置,否则不起作用。
二、角度定位
layout_constraintCircle
layout_constraintCircleAngle
layout_constraintCircleRadius
角度定位是指用一个角度和一个距离来约束两个控件的中心。
app:layout_constraintCircle="@+id/textView2"
app:layout_constraintCircleAngle=“120”
app:layout_constraintCircleRadius=“60dp”
三、实现居中效果
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
意思是把控件的上下左右约束在布局的上下左右并且权重相同,这样就能把控件放在布局的中间了。另外介绍一种偏移属性,赋值在0-1之间,中间值为0.5。
layout_constraintHorizontal_bias 水平偏移
layout_constraintVertical_bias 垂直偏移
四、约束尺寸
控件的尺寸可以通过四种不同方式指定:
1、使用指定的绝对尺寸
2、使用wrap_content,让控件自己计算大小。可以使用下列属性来控制最大、最小的高度或宽度:
android:minWidth 最小的宽度
android:minHeight 最小的高度
android:maxWidth 最大的宽度
android:maxHeight 最大的高度
3、使用 0dp (MATCH_CONSTRAINT),官方推荐设置 0dp 配合约束代替match_parent.
当宽度设为0dp,左右两边约束parent的左右两边,并设置左右边距为50dp,效果如下:
4、宽高比。当宽或高至少有一个尺寸被设置为0dp时,可以通过属性layout_constraintDimensionRatio设置宽高比。
app:layout_constraintDimensionRatio="1:1"
可以在前面加W或H,分别指定宽度或高度限制。 例如:
app:layout_constraintDimensionRatio="H,2:3" 高:宽=2:3
app:layout_constraintDimensionRatio="W,2:3" 宽:高=2:3
五、 链
如果两个或以上控件的左右相互约束,就可以认为是他们是一条链(图为横向的链,纵向同理)。在as里选择多个组件,然后右键即可创建链。通过对链的整体属性设置,来调整多个控件的布局。但具体的应用场景不详 -_-
一条链的第一个控件是这条链的链头,我们可以在链头中设置 layout_constraintHorizontal_chainStyle来改变整条链的样式。
- CHAIN_SPREAD —— 展开元素 (默认);
- CHAIN_SPREAD_INSIDE —— 展开元素,但链的两端贴近parent;
- CHAIN_PACKED —— 链的元素将被打包在一起。
六、 辅助工具
1、 Barrier:在容器某一位置设置一道屏障,其它组件的位置可以基于这个屏障去设置。比如,让C始终在AB的右边,但是不确定AB的宽度,可以基于AB设置一道屏障,C的位置以屏障为准设置即可。
2、Group
Group可以把多个控件归为一组,方便隐藏或显示一组控件。
3、Placeholder
Placeholder指的是占位符。在Placeholder中可使用setContent()设置另一个控件的id,使这个控件移动到占位符的位置。
4、 Guideline
Guildline即辅助线,在预览的时候帮助你完成布局(不会显示在界面上)。