android 基本布局
@author lisiwen
@createTIme 2022/04/10
文章中代码链接:https://github.com/NET-lisiwen/UILayoutTest
一个丰富的界面是由很多控件组成的,那么我们才能让各个控件都有条不紊地摆放在界面上,而不是乱糟糟的呢?这就需要借助布局来实现了。布局是一种可用于放置很多控件的容器,它可以按照一定的而规律调整内部控件的位置,从而编写出精美的界面。当然,布局的内部除了放置控件外,也可以放置布局,通过多层布局的嵌套,我们就能够完成一些比较复杂的界面实现,如下图就很好的展示了他们之间的关系

1.LinearLayout
LInearLayout又称线性布局,是一种非常常用的布局。正如它的名字所描述的一样,这个布局会将它所包含的控件在线性方向上依次排列。
既然是线性排列的,肯定就不值有一个方向,可以通过android:orientation来指定排列的方向,vertical为垂直方向排列,horizontal为水平方向排列。解析来可以体验一下 代码如下所示
<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="wrap_content"
android:layout_height="wrap_content"
android:text="button1"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="button2"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="button3"/>
</LinearLayout>
我们在LinearLayout中添加了三个button,每个button长和宽都为wrap_content,并且指定了排列方向为vertical,运行结果如下

接下来我们修改一下排列方向为horizontal排列放下代码如下
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
...
</LinearLayout>
这里将android:orientation属性值改成了horizontal,这就意味着要让LinearLayout中的元素水平方向排列。重新运行结果如下

需要注意的是,如果android:orientation属性值设置成了horizontal,那么内部元素的宽就不可以设置match_parent,否则一个空降就会将水平方向占满,其他控件就没有空间来展示了,同样道理排列方向是vertical,元素的高也不可以设置成match_parent。
接下来看android:layout_gravity这个属性,这个和之前介绍控件的时候使用的android:gravity看起来有点像哈,其实可以理解为android:gravity为内部元素的对齐方式,android:layout_gravity为当前控件在父布局中的对齐方式,这两个属性的可选值是差不多的,但是需要注意,当LinearLayout的排列方向是horizontal时,只有垂直方向的对齐方式才会生效,因为毕竟水平方向元素数量还有宽度都不是固定的,因此无法指定水平方向上的对齐方式。同样的道理当对齐方式是vertical时只有水平方向的对齐方式才会生效。修改activity_main.xml的代码,如下所示
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:text="button1"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="button2"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:text="button3"/>
</LinearLayout>
由于目前LinearLayout的排列方式为horizontal所以只有垂直方向上的对齐方式,将第一个button对齐方式设置为top,第二个button设置为center_vertical,第三个设置为bottom。重新运行程序,如下图所示
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-D1SFOpir-1649562096472)(pic/android基本布局/image-20220410102822301.png)]
这时候可以试一下将第1个按钮对齐方式设置为水平方向居中会发生什么,修改activity_main.xml的代码,如下所示
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
...
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="button1"/>
</LinearLayout>
可以看到将按钮设置成水平方向居中,重新运行程序

可以看到设置的属性并未生效,button1并没有水平居中,可以验证之前的说法,当垂直排列的时候,设置水平方向上的对齐方式并不会生效。
接下来来学习LinearLayout另一个重要的属性android:layout_weight。这个属性允许我们使用比例的方式来指定控件的大小,它在手机屏幕的适配性方面可以起到非常重要的作用。比如我们正在写一个消息发送界面,需要一个文本编辑框和一个发送按钮,修改activity_main.xml的代码,如下所示
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<EditText
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:hint="type something" />
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Send" />
</LinearLayout>
会发现,这里将TextView和Button的宽设置成了0dp,因为这里使用了android:layout_weight属性,此时控件的宽度就不再由android:layout_width来控制了,这里指定成0dp是一种规范的写法。
然后在TextView和Button将android:layout_weight都设置成1,表示两个控件在水平方向上评分宽度。
重新运行程序如下所示

为什么将android:layout_weight都设置成1就会平分屏幕宽度?其实原理很简单,系统会先把LinearLayout下所有控件指定的layout_weight值相加,得到一个总值,然后每个控件所占大小比例就是用改控件的layout_weight值除以刚才算出来的总值。
我们也可以修改layout_weight属性已让其展示的更加美观,修改activity_main.xml的代码,如下所示
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<EditText
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:hint="type something" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Send" />
</LinearLayout>
这里我们仅仅指定了EditText控件的weight,并且将Button的宽度设置成了wrap_content,这里Button的宽度仍然按照wrap_content来计算,而EditText则会占满屏幕剩余的所有控件。使用这种方式编写的界面,不仅可以适配各种屏幕,并且看起来也会舒服很多。重新运行程序,如下图所示

2.RelativeLayout
RelativeLayout又称作相对布局,也是一种非常常用的布局方式,和LInearLayout的排列规则不同,RelativeLayout显得更加的所以,它可以通过相对定位的方式让控件出现在布局的任意位置。也正是因为如此,RelativeLayout中的属性非常多,不过这些属性都是有规律可循的,其实并不难理解和记忆。我们还是通过实践来体会一下,修改activity_main.xml的代码,如下所示
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:text="button1" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_alignParentRight="true"
android:text="button2" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="button3" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentBottom="true"
android:text="button4" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
android:text="button5" />
</RelativeLayout>
以上代码还是比较好理解的,button1为父布局左上角对齐,button2为父布局右上角对齐,button3在父布局居中显示,button4父布局左下角对齐,button5在父布局右下角对齐。虽然layout_alignParentLeft、layout_alignParentTop、layout_alignParentRight、layout_alignParentBottom和layout_centerInParent之前根本没见过,但是看名字基本上就了解了这个属性是干什么的。重新运行程序,结果如下

上边的例子中每个控件都是相对于父布局进行定位的,那控件可不可以相对于控件进行定位呢?结果是当然可以了,修改activity_main.xml的代码,如下所示
<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_above="@id/button3"
android:layout_toLeftOf="@id/button3"
android:text="button1" />
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="@id/button3"
android:layout_toRightOf="@id/button3"
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_below="@id/button3"
android:layout_toLeftOf="@id/button3"
android:text="button4" />
<Button
android:id="@+id/button5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/button3"
android:layout_toRightOf="@id/button3"
android:text="button5" />
</RelativeLayout>
这次的代码比上次的复杂一点,但是也是又规律可循的使用layout_above可以让一个控件在另一个控件的上方,需要为这个属性指定相对控件的id的应用,这里我们填入了@id/button3,表示让控件位于Button3的上方。其他属性也是相似的layout_below表示让一个控件位于另一个控件的下方,layout_toLeftOf表示让一个控件位于另一个控件的左侧,layout_toRightOf表示让一个控件位于另一个控件的右侧
RelativeLayout中还有另外一句相对控件进行定位的属性,android:layout_alignLeft表示让一个控件的左侧边缘和另一个控件的左边缘对齐,android:layout_alignRight表示让一个控件的右边缘和另一个控件的右边缘对齐。此外也有android:layout_alignTop和android:layout_alignBottom道理都是一样的,这里就不仔细讲解了。
虽然说RelativeLayout属性有点多,但是也都是有规律可循的,使用起来也使布局更加的自由。
3.FrameLayout
FrameLayout又称做帧布局,它相比前面的两种布局就简单太多了,因此他的应用场景少了很多。这种布局没有丰富的定位方法,所有的控件都会默认放在布局的左上角。让我们通过例子看一下,修改activity_main.xml的代码,如下所示
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="this is text view........."/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="button"/>
</FrameLayout>
FrameLayout中只是放置了一个TextView和Button。重新运行程序,如下所示

可以看到,文字和按钮都位于布局的左上角,由于Button是在TextView之后添加的,因为按钮压在了文字上方。
当然除了这种默认的效果之外,我们还可以使用layout_gravity属性来注定控件在布局中的对齐方式,这和LinearLayout中的用法是相似的,修改activity_main.xml的代码,如下所示
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="left"
android:text="this is text view........."/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:text="button"/>
</FrameLayout>
这里我们将TextView致电给左对齐,Button右对齐,重新运行程序,结果如下图

总体来讲由于定位方式的欠缺,FrameLayout的应用场景相对偏少一些,因此在实际开发中,经常使用它包裹单个控件,来进行控件的布局的控制。
本文介绍了Android中的三种基本布局:LinearLayout、RelativeLayout和FrameLayout。LinearLayout按照线性方向排列控件,支持垂直和水平排列,并可通过android:layout_weight属性实现控件按比例分配空间。RelativeLayout通过相对定位实现更灵活的布局效果,允许控件相对于父布局或其他控件定位。FrameLayout则简单直接,所有控件默认左上角对齐,但可通过layout_gravity调整对齐方式。

2573

被折叠的 条评论
为什么被折叠?



