Android第一行代码——布局

文章目录

前言

一、线性布局        LinerLayout

二、相对布局        RelativeLayout

三、帧布局        FrameLayout



前言

        一个丰富的界面总是要由很多个控件组成的,那我们如何才能让各个控件都有条不紊地摆放在界面上,而不是乱糟糟的呢?这就需要借助布局来实现了。布局是一种可用于放置很多控件的容器,它可以按照一定的规律调整内部控件的位置,从而编写出精美的界面。当然,布局的内部除了放置控件外,也可以放置布局,通过多层布局的嵌套,我们就能够完成一些比较复杂的界面实现,图4.15 很好地展示了它们之间的关系。

图4.15        布局和控件的关系

一、线性布局        LinerLayout

        LinearLayout 又称作线性布局,是一种非常常用的布局。正如它的名字所描述的一样,这个布局会将它所包含的控件在线性方向上依次排列。相信你之前也已经注意到了,我们在上一节中学习控件用法时,所有的控件就都是放在 LinearLayout 布局里的,因此上一节中的控件也确实是在垂直方向上线性排列的。

        既然是线性排列,肯定就不只有一个方向,那为什么上一节中的控件都是在垂直方向排列的呢?这是由于我们通过 android:orientation 属性指定了排列方向是 vertical ,如果指定的是 horizontal ,控件就会在水平方向上排列了。

android:orientation="vertical"

        vertical            垂直方向排列

        horizontal        水平方向排列

        下面我们通过实战来体会一下,新建一个 UILayoutTest  项目,并让Android Studio 自动帮我们创建好Activity ,Activity 名和布局名都使用默认值。

        修改activity_main.xml 中的代码,如下所示:

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

  <Button
      android:id="@+id/button1"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="Button 1"/>

    <Button
        android:id="@+id/button2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button 2"/>

    <Button
        android:id="@+id/button3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button 3"/>

</LinearLayout>

        我们在LinearLayout 中添加了3个Button ,每个Button 的长和宽都是wrap_content,并指定了排列方向是vertical。现在运行一下程序,效果如 图4.16 所示。

图4.16        LinearLayout 垂直排列

        然后我们修改一下LinearLayout的排列方向,如下所示:

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

 ...

</LinearLayout>

                这里将 android:orientation 属性的值改成了 horizontal,这就意味着要让 LinearLayout 中的控件在水平方向上依次排列。当然,如果不指定 android:orientation 属性的值,默认的排列方向就是 horizontal。重新运行一下程序,效果 如图4.17 所示。

图4.17        LinearLayout 水平排列

        需要注意,如果 LinearLayout  的排列方向是 horizontal,内部的控件就绝对不能将宽度指定 为 match_parent,否则,单独一个控件就会将整个水平方向占满,其他的控件就没有可放置 的位置了。同样的道理,如果 LinearLayout 的排列方向是 vertical,内部的控件就不能将高度指定为 match_parent

        下面来看 android:layout_gravity 属性,它和我们上一节中学到的 android:gravity 属性看起来有些相似,这两个属性有什么区别呢?其实从名字就可以看出,android:gravity 用于指定文字在控件中的对齐方式,而 android:layout_gravity 用于指定控件在布局中的对齐方式。android:layout_gravity 的可选值和 android:gravity 差不多,但是需要注 意,当 LinearLayout 的排列方向是 horizontal 时,只有垂直方向上的对齐方式才会生效。因为此时水平方向上的长度是不固定的,每添加一个控件,水平方向上的长度都会改变,因而无法指定该方向上的对齐方式。同样的道理,当 LinearLayout 的排列方向是 vertical 时,只有水平方向上的对齐方式才会生效。

        修改 activity_main.xml 中的代码,如下所示:

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:background="#F5F6F7"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="top"
        android:text="Button 1"/>

    <Button
        android:id="@+id/button2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:text="Button 2"/>

    <Button
        android:id="@+id/button3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom"
        android:text="Button 3"/>
</LinearLayout>

        由于目前 LinearLayout 的排列方向是 horizontal,因此我们只能指定垂直方向上的排列方 向,将第一个 Button 的对齐方式指定为 top,第二个 Button 的对齐方式指定为 center_vertical,第三个 Button 的对齐方式指定为 bottom。重新运行程序,效果 如图4.18 所示。

图4.18        指定 layout_gravity 的效果

        接下来我们学习 LinearLayout 中的另一个重要属性——android:layout_weight。这个属 性允许我们使用比例的方式来指定控件的大小,它在手机屏幕的适配性方面可以起到非常重要的作用。比如,我们正在编写一个消息发送界面,需要一个文本编辑框和一个发送按钮,修改activity_main.xml 中的代码,如下所示:

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:background="#F5F6F7"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <EditText
        android:id="@+id/input_message"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:hint="Type something"/>

    <Button
        android:id="@+id/send"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text="Send"/>
</LinearLayout>

        你会发现,这里竟然将 EditText 和 Button 的宽度都指定成了 0dp ,这样文本编辑框和按钮还能显示出来吗?不用担心,由于我们使用了 android:layout_weight 属性,此时控件的宽度就不应该再由 android:layout_width 来决定了,这里指定成 0dp 是一种比较规范的写法。 然后在EditText 和 Button 里将 android:layout_weight 属性的值指定为 1,这表示 EditText 和 Button 将在水平方向平分宽度。 重新运行程序,你会看到如图4.19 所示的效果。

图4.19        指定 layout_weight 的效果

        为什么将 android:layout_weight 属性的值同时指定为 1 就会平分屏幕宽度呢?其实原理很 简单,系统会先把 LinearLayout 下所有控件指定的 layout_weight 值相加,得到一个总值, 然后每个控件所占大小的比例就是用该控件的 layout_weight 值除以刚才算出的总值。因此如果想让EditText 占据屏幕宽度的 3/5 ,Button 占据屏幕宽度的 2/5 ,只需要将 EditText 的 layout_ weight改成 3,Button 的 layout_weight 改成 2 就可以了。 我们还可以通过指定部分控件的layout_weight 值来实现更好的效果。修改 activity_main. xml 中的代码,如下所示 

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:background="#F5F6F7"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <EditText
        android:id="@+id/input_message"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:hint="Type something"/>

    <Button
        android:id="@+id/send"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Send"/>
</LinearLayout>

        这里我们仅指定了 EditText 的 android:layout_weight 属性,并将 Button 的宽度改回了 wrap_content。这表示 Button 的宽度仍然按照 wrap_content 来计算,而 EditText 则会占满屏幕所有的剩余空间。使用这种方式编写的界面,不仅可以适配各种屏幕,而且看起来也更加舒服。重新运行程序,效果如图4.20 所示。

图4.20        使用 layout_weight 实现宽度自适配效果


二、相对布局        RelativeLayout

        RelativeLayout 又称作相对布局,也是一种非常常用的布局。和 LinearLayout 的排列规则不 同,RelativeLayout 显得更加随意,它可以通过相对定位的方式让控件出现在布局的任何位置。也正因为如此,RelativeLayout 中的属性非常多,不过这些属性都是有规律可循的,其实 并不难理解和记忆。我们还是通过实践来体会一下,修改 activity_main.xml 中的代码,如下所示:

<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <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="Button 1"/>

    <Button
        android:id="@+id/button2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_alignParentTop="true"
        android:text="Button 2"/>

    <Button
        android:id="@+id/button3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:text="Button 3"/>

    <Button
        android:id="@+id/button4"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentBottom="true"
        android:text="Button 4"/>

    <Button
        android:id="@+id/button5"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_alignParentBottom="true"
        android:text="Button 5"/>

</RelativeLayout>

        以上代码不需要做过多解释,因为实在是太好理解了。我们让 Button 1 和父布局的左上角对 齐,Button 2 和父布局的右上角对齐,Button 3 居中显示,Button 4 和父布局的左下角对齐, Button 5 和父布局的右下角对齐。虽然 android:layout_alignParentLeft、 android:layout_alignParentTop、android:layout_alignParentRight、 android:layout_alignParentBottom、android:layout_centerInParent 这几个属 性我们之前都没接触过,可是它们的名字已经完全说明了它们的作用。重新运行程序,效果 如图4.21 所示。

图4.21        相对父布局定位的效果

         上面例子中的每个控件都是相对于父布局进行定位的,那控件可不可以相对于控件进行定位 呢?当然是可以的,修改 activity_main.xml 中的代码,如下所示:

<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:background="#F5F6F7"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/button3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:text="Button 3"/>

    <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="Button 1"/>

    <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="Button 2"/>

    <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="Button 4"/>

    <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="Button 5"/>
    
</RelativeLayout>

        这次的代码稍微复杂一点,不过仍然是有规律可循的。android:layout_above 属性可以让 一个控件位于另一个控件的上方,需要为这个属性指定相对控件 id 的引用,这里我们填入了 @id/button3,表示让该控件位于 Button 3 的上方。其他的属性也是相似的,android: layout_below 表示让一个控件位于另一个控件的下方,android:layout_toLeftOf 表示 让一个控件位于另一个控件的左侧,android:layout_toRightOf 表示让一个控件位于另一 个控件的右侧。注意,当一个控件去引用另一个控件的 id 时,该控件一定要定义在引用控件的后面,不然会出现找不到 id 的情况。重新运行程序,效果 如图4.22 所示。

图4.22        相对于控件定位的效果

 android:layout_above="@id/button3"                表示该控件位于 Button 3 的上方   

 android:layout_below="@id/button3"                表示该控件位于 Button 3 的下方 

 android:layout_toLeftOf="@id/button3"             表示该控件位于 Button 3 的左方 

 android:layout_toRightOf="@id/button3"          表示该控件位于 Button 3 的右方  

        RelativeLayout 中还有另外一组相对于控件进行定位的属性,android:layout_alignLeft 表示让一个控件的左边缘和另一个控件的左边缘对齐,android:layout_alignRight 表示让一个控件的右边缘和另一个控件的右边缘对齐。此外,还有 android:layout_alignTopandroid:layout_alignBottom,道理都是一样的,我就不再多说了,这几个属性就留给你 自己去尝试吧。

android:layout_alignLeft="true"         表示让一个控件的左边缘和另一个控件的左边缘对齐

android:layout_alignRight="true"       表示让一个控件的右边缘和另一个控件的右边缘对齐 

android:layout_alignTop="true"          表示让一个控件的上边缘和另一个控件的上边缘对齐 

android:layout_alignBottom="true"    表示让一个控件的下边缘和另一个控件的下边缘对齐


  三、帧布局        FrameLayout

        FrameLayout 又称作帧布局,它相比于前面两种布局就简单太多了,因此它的应用场景少了很多。这种布局没有丰富的定位方式,所有的控件都会默认摆放在布局的左上角。让我们通过例 子来看一看吧,修改activity_main.xml 中的代码,如下所示:

<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:background="#F5F6F7"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="This is TextView"/>
    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button"/>
    
</FrameLayout>

        FrameLayout 中只是放置了一个TextView 和一个Button 。重新运行程序,效果 如图4.23 所示。

图4.23        FrameLayout 运行效果

        可以看到,文字和按钮都位于布局的左上角。由于 Button 是在 TextView 之后添加的,因此按钮压在了文字的上面。 

        当然,除了这种默认效果之外,我们还可以使用 layout_gravity 属性来指定控件在布局中的 对齐方式,这和 LinearLayout 中的用法是相似的。修改 activity_main.xml 中的代码,如下所 示:

<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:background="#F5F6F7"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="left"
        android:text="This is TextView"/>
    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:text="Button"/>

</FrameLayout>

        我们指定 TextView 在 FrameLayout 中居左对齐,指定 Button 在 FrameLayout 中水平居中对齐,然后重新运行程序,效果 如图4.24 所示。

图4.24        指定 layout_gravity 的效果

        总体来讲,由于定位方式的欠缺,FrameLayout 的应用场景相对偏少一些,不过在下一章中介绍 Fragment 的时候我们还是可以用到它的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值