在Android开发中,界面设计是门面,是必不可少的元素,这就需要借助布局实现。
布局是一种可用于放置很多控件甚至嵌套布局的容器,它可以按照一定规律调整内部控件或者布局的位置(比如控件和父容器之间以及控件与控件之间的位置关系),甚至还能在布局中嵌套布局,从而实现开发需求,编写出精美的界面。
接下来介绍四种布局:
- FrameLayout
- LinearLayout
- RelativeLayout
- PercentLayout
当然首先我们得知道如何创建布局文件(.xml):
1.LinearLayout(线性布局):
一种将其包含的控件在水平或垂直线性方向上依次排列的布局。
从最外层的属性开始:
android:orientation:可选值为vertical和horizontal,分别代表布局中控件按垂直方向排列和水平方向排列线性排列,是一个全局属性;
android:gravity:可选值为center(水平垂直方向均居中)|center_vertical(垂直方向居中)|center_horizontal(水平方向居中)|left/start(向左对齐)|right/end(向右对齐)|top(顶部对齐)|bottom(底部对齐),其中各属性可通过“|”级联使用,如android:gravity=“left|bottom”;
android:layout_gravity:可选值与android:gravity相同,不同的是android:layout_gravity控制的是控件本身相对于父容器的位置,而android:gravity控制的的容器中控件/控件中文字的位置。
注意:orientation为vertical时,只有水平方向上的对齐方式生效,因为此时垂直方向上由于控件数量未知长度不固定;同理orientation为horizontal时,只能指定竖直方向上的对齐方式。
android:layout_weight:这是线性布局中一个很特殊的属性,它代表了控件在布局中所占的比例;上图中两个TextView所占比重为1:1,所以两者各占总宽度的一半,若为其他比例也按同理推断;实际开发中按下图效果更好:仅指定某个控件的比例,这样剩下的控件会自动填充剩下的空间,有利于进行屏幕适配;
2.RelativeLayout(相对布局):
一种通过相对定位,即控件相对控件或控件相对布局的方式控制控件位置的布局,它可以让控件出现在布局的任何位置,十分常用。正因为这种定位方式,相对布局的位置属性也相当多,虽然看似复杂,但其名字已经很直接地表达了其代表的含义。
相对于父容器的属性:
android:layout_alignParentBottom(与父容器底部对齐,true或false)、
android:layout_alignParentTop(与父容器顶部对齐,true或false) 、
android:layout_alignParentLeft(与父容器最左边对齐,true或false) 、
android:layout_alignParentRight(与父容器最右边对齐,true或false)、
android:layout_marginTop(到父容器顶部的距离,单位dp)、
android:layout_marginBottom(到父容器底部的距离)、
android:layout_marginLeft(到父容器左端的距离)、
android:layout_marginRight(到父容器右端的距离)、
android:layout_margin(与父容器四周之间的距离)、
android:layout_centerVertical(在父容器中垂直居中,true或false)、
android:layout_centerHorizontal(在父容器中水平居中,true或false)、
android:layout_centerInParent(在父容器中水平垂直居中,true或false)
相对于控件的属性:
android:layout_below(位于某控件下方,以id标记)、
android:layout_above(位于某控件上方,以id标记)、
android:layout_toLeftOf(位于某控件左方,以id标记)、
android:layout_toRightOf(位于某控件右方,以id标记)、
android:layout_alignBottom(与某控件底部对齐,以id标记)、
android:layout_alignTop(与某控件顶部对齐,以id标记) 、
android:layout_alignLeft(与某控件左边缘对齐,以id标记) 、
android:layout_alignRight(与某控件右边缘对齐,以id标记)、
android:layout_alignBaseline(与某控件的文本内容在一条直线上)
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:text="Button1"/>
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_alignParentRight="true"
android:text="Button2"/>
<Button
android:id="@+id/button3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="Button3"/>
<Button
android:id="@+id/button4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:text="Button4"/>
<Button
android:id="@+id/button5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:text="Button5"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/button3"
android:layout_centerInParent="true"
android:text="Button6"/>
</RelativeLayout>
3.FrameLayout(帧布局):
一种将所有控件默认摆放在布局左上角的布局,应用场景相对较少。
该布局中控件的位置摆放可通过android:layout_gravity设置,用法类似LinearLayout。
4.PercentFrameLayout & PercentRelativeLayout(百分比布局):
一种可以直接指定控件在布局中所占百分比的布局,可以轻松实现平分布局甚至按任意比例分割布局的效果。由于百分比布局是一种新增布局,因此需要添加相应依赖:
注意添加的百分比布局的依赖的版本号应当与当前SDK版本号相同,否则无法成功构建。
<?xml version="1.0" encoding="utf-8"?>
<android.support.percent.PercentFrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/button1"
android:layout_gravity="top|start"
app:layout_widthPercent="50%"
app:layout_heightPercent="50%"
android:text="Button1"/>
<Button
android:id="@+id/button2"
android:layout_gravity="top|end"
app:layout_widthPercent="50%"
app:layout_heightPercent="50%"
android:text="Button2"/>
<Button
android:id="@+id/button3"
android:layout_gravity="bottom|start"
app:layout_widthPercent="50%"
app:layout_heightPercent="50%"
android:text="Button3"/>
<Button
android:id="@+id/button4"
android:layout_gravity="bottom|end"
app:layout_widthPercent="50%"
app:layout_heightPercent="50%"
android:text="Button4"/>
</android.support.percent.PercentFrameLayout>
在百分比布局中,实际上是通过app:layout_widthPercent和app:layout_heightPercent来设置控件的宽高,其对应的百分比值代表的是控件在布局中的所占比例,同时如果宽比例或者高比例相加超过100%,控件是可以重叠的,如下图:
同理PercentRelativeLayout的设置操作也与RelativeLayout基本相同,因此不做赘述。
5.ConstrainLayout(约束布局)
Deprecated consider using ConstraintLayout and associated layouts instead. The following shows how to replicate the functionality of percentage layouts with a ConstraintLayout. The Guidelines are used to define each percentage break point, and then a Button view is stretched to fill the gap:
从以上信息可得知,现今的百分比布局已经废弃,Google推荐我们使用ConstrainLayout替代它,并提供了一个通过Guildline定位的Button:
我们可以直接通过拖动Guildline(更改其在布局中的比例)来设置Button的位置,看起来是不是很方便呢?详细学习可参照最全面的ConstrainLayout教程。
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.constraint.Guideline
android:id="@+id/left_guideline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_begin="62dp"/>
<android.support.constraint.Guideline
android:id="@+id/right_guideline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent=".85"/>
<android.support.constraint.Guideline
android:id="@+id/bottom_guideline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent=".85"/>
<Button
android:id="@+id/button"
android:layout_width="0dp"
android:layout_height="0dp"
android:text="Button"
app:layout_constraintBottom_toBottomOf="@+id/bottom_guideline"
app:layout_constraintLeft_toLeftOf="@+id/left_guideline"
app:layout_constraintRight_toRightOf="@+id/right_guideline"
app:layout_constraintTop_toTopOf="@+id/top_guideline"/>
<android.support.constraint.Guideline
android:id="@+id/top_guideline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent=".15"/>
</android.support.constraint.ConstraintLayout>
6.布局原则
- 相同布局层次下,线性布局比相对布局的性能高。
- 使用增加UI的复用效率:可把重复使用的控件抽取出来放在一个xml文件里,并在需要它的xml文件里通过include标签引用。这样做也保证了UI布局的规整和易维护性。下图是一个简单的示例。
- 使用标签减少布局的嵌套层次,它和一样可以用来引入一个外部布局,但不同的是ViewStub引入的布局不占用布局空间,在解析layout布局时可节省CPU和内存。使用时通过inflate方法使之在布局中显示出来。
谢谢阅读!