Android中的UI一般都是由多个Activity组成,视图都是通过一个个组件构成,像Button、TextView、ImageView等,而包裹这些组件的我们称之为布局
。
Android中传统的五大布局分别是LinearLayout
(线性布局)、RelativeLayout
(相对布局)、FrameLayout
(帧布局)、AbsoluteLayout
(绝对布局)、TableLayout
(表格布局)。
在Android Studio 2.2以后新增了一个布局:ConstraintLayout
(约束布局)。
Linearlayout
LinearLayout,我们称之为线性布局,因为它的布局的排列是线性的,要么水平,要么垂直,通过android:orientation="vertical|horizontal"
来控制。
属性
我们用一张图来概括下LinearLayout的所持有的属性及其用法。
说下layout_gravity
和gravity
的区别,第一个是用来设置本身控件在父控件中的对齐方式,第二个是用来设置控件内的对齐方式,和margin和padding作用类似,一个对外,一个对内。
linearLayout
最具有特点的一个属性就是layout_weight
。
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"/>
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="2"/>
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="3"/>
</LinearLayout>
复制代码
看上面这个例子,做一下简单解释:这就相当于把一个屏幕的宽度平分为6份,第一个TextView占一份,第二个占两份,第三个占三份。
RelativeLayout
RelativeLayout
,相对布局,可以设置控件之间的位置关系。
我们看一个RelativeLayout
的特有属性。
FrameLayout
FrameLayout
,框架布局,也叫做帧布局,新加入的控件永远在前一个控件之上,都是放在左上角位置,这也是它的特点之一。
AbsoluteLayout
AbsoluteLayout
,绝对布局,通过坐标来确定控件的位置。左上角为(0.0).
相对来说,它的特有属性就是layout_x
和layout_y
,分别制定控件的x坐标和y坐标。
AbsoluteLayout
现在已经被废弃了,不推荐使用,只做个了解就好。
TableLayout
TableLayout
将子元素排成行和列,由多个TableRow
对象组成,每个TableRow
代表一行。
TableLayout
的子节点不能制定layout_width
属性,宽度总是MATCH_PARENT
。
下面是其特有的属性:
ConstraintLayout
ConstraintLayout
可以让我们更好地进行可视化编程,同时它也会减小嵌套的层级,有利于快速渲染。
每个控件有水平和垂直两个方向上的约束,共四个约束。
对于ConstraintLayout包含的控件不建议使用MATCH_PARENT
,建议使用MATCH_CONSTRAINT
(0dp)和水平垂直约束来设置。
看下其特有的属性:
借用官网上的图片,来看下两个控件的位置关系。
看图,就可以很好地去理解 layout_constraintLeft_toRightOf
这个属性的意思:控件的左侧位于约束控件的右侧,就相当于控件在另一个控件的右边。
ConstraintLayout可以设置相对于隐藏控件的距离,也就是图中的属性layout_goneMarginStart
等。
bias倾斜
当我们想设置一个水平居中的效果时,这样设置:
<android.support.constraint.ConstraintLayout ...>
<Button android:id="@+id/button" ...
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent/>
</>
复制代码
显示的效果就是这样:
如果再加上一个这个属性呢?app:layout_constraintHorizontal_bias="0.3"
复制代码
可以看到效果变成了这个样子:
bias默认设置的是左边和上边的拉力,0~1之间。越大越靠右或者越靠下。
圆形定位
圆形定位是在1.1之后出现的,您可以在一个角度和一个距离上约束一个小部件中心相对于另一个小部件中心。
例如:
<Button android:id="@+id/buttonA" ... />
<Button android:id="@+id/buttonB" ...
app:layout_constraintCircle="@+id/buttonA"
app:layout_constraintCircleRadius="50dp"
app:layout_constraintCircleAngle="60" />
复制代码
强制约束
控件的宽度设置为WRAP_CONTENT
时,如果控件的宽度超过了约束的宽度,这时约束就会失效。可以通过设置强制约束来限制控件的宽度在我们所希望的 约束之内。
例如:
<Button
android:id="@+id/btn_A"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="16dp"
android:text="A"
app:layout_constraintLeft_toLeftOf="parent"/>
<Button
android:id="@+id/btn_B"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="B"
app:layout_constraintLeft_toRightOf="@+id/btn_A"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/btn_A"/>
复制代码
如果button B的内容过长,约束就会失效,可以加上这句来强制约束:
app:layout_constrainedWidth=”true”
复制代码
ratio 比率
我们可以用ConstraintLayout来设置宽高比,前提是该控件的宽高至少有一个为0dp
。
看下面的例子:
<Button android:layout_width="wrap_content"
android:layout_height="0dp"
app:layout_constraintDimensionRatio="1:1" />
复制代码
这样显示的就是一个正方形。
<Button android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintDimensionRatio="H,16:6"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"/>
复制代码
其中的H
是指约束高,宽高比为16:6,宽度为整个屏幕的宽度。
chains
如果通过双向连接将一组控件连接在一起,将它们称之为一个链,如下图所示:
在这个链的最左侧叫做链头,可以在其身上设置一些属性,来决定链的 展示效果
这个属性就是layout_constraintHorizontal_chainStyle
,他有四种值可以设置:CHAIN_SPREAD
、Weighted
、CHAIN_SPREAD_INSIDE
、CHAIN_PACKED
。
- spread + 宽度为0,显示为多个控件间距等分,如上图
Spread Chain
。宽度为0,和Weighted效果一样。 - spread_inside, 控件之间间距相等,如上图
Spread Inside Chain
。 - Weighted,相当于LinearLayout中的权重,也可以用
layout_constraintHorizontal_weight
来设置。 - packed,链左右有间距,如上图
Packed Chain
Guideline
Guideline是一个辅助线,横向或纵向,相当于LinearLayout中的android:orientation="vertical|horizontal"
。
除此之外,Guideline还有三个属性可以设置其定位:
layout_constraintGuide_begin
距离父容器起始位置的距离(左侧或顶部)layout_constraintGuide_end
距离父容器结束位置的距离(右侧或底部)layout_constraintGuide_percent
距离父容器宽度或高度的百分比
Barrier
1.1之后新增的一个特性,障碍约束,可以将多个组件作为一个整体,通过app:constraint_referenced_ids
来设置。
app:barrierDirection
来设置其方向。
FlexboxLayout
相信做过React-Native
或者前端的朋友,会对Flex很熟悉,FlexboxLayout布局就是根据css的 CSS Flexible Box Layout Module 变化而来。
来看一下它的特有属性,几乎和css中flex的属性一样。
说下主轴和辅轴的概念,flexDirection
是用来设置主轴的方向的,如果主轴为row
:水平,那么辅轴方向就是垂直的,反之,如果主轴是垂直的,辅轴就是水平的。
总结
这里,简单讲几个布局做了下叙述,并没有很多实例来详细地为大家展示其具体的效果,大家可以自己动手试一下,所谓多看不如多做,如有不对的地方,欢迎批评指正。
参考
解析ConstraintLayout的性能优势
ConstraintLayout官方文档
Guideline
flexbox-layout
多积累、多总结、多思考,每天比昨天多努力一点点。