天天看点

Android基础之常用布局介绍

  一直以来,都有写博客的打算,最近实在是懒散惯了,还是应该动动手,内容可能有瑕疵,希望各位大神踊跃发言,提点建议,不胜感激。

  在 android 中我们常用的布局方式有这么几种:RelativeLayout,LinearLayout,FrameLayout,TableLayout,AbsoluteLayout,当然有些布局已经不再常用,例如TableLayout,只介绍前三个,还有其他布局如GridLayout,TabLayout等等,有兴趣自行研究。

1.RelativeLayout ( 相对布局 ):

  顾名思义,相对布局,就是相对于其他控件的布局,相信我这样说,大家很好的理解,然而我们都知道。在这里,我们需要理解这么一个常识,一个控件,给定它的宽高属性之后,如果不指定它的位置,那么它就是排列在手机屏幕上的左上角的位置,也就是说,一个控件的默认位置就是在屏幕的左上角,当你指定它在布局中的位置有效时,它才会排列在一个新的位置上。

  相对布局分为两个方面:一是控件相对于其他控件,二是控件相对于父布局。

  一、控件相对于其他控件

Android基础之常用布局介绍
Android基础之常用布局介绍

  常用属性有以下这些:属性值必须为 id 的引用名“ @id/相对控件的id ”

  android:layout_below                在某元素的下方

  android:layout_above                在某元素的上方

  android:layout_toLeftOf              在某元素的左边

  android:layout_toRightOf             在某元素的右边

  android:layout_alignTop              本元素的上边缘和某元素的的上边缘对齐

  android:layout_alignLeft             本元素的左边缘和某元素的的左边缘对齐

  android:layout_alignBottom            本元素的下边缘和某元素的的下边缘对齐

  android:layout_alignRight            本元素的右边缘和某元素的的右边缘对齐

  当然需要设置两个控件之间的距离,需要用到以下属性(单位为px或dp):

  android:layout_marginBottom              离某元素底边缘的距离

  android:layout_marginLeft               离某元素左边缘的距离

  android:layout_marginRight              离某元素右边缘的距离

  android:layout_marginTop               离某元素上边缘的距离

  二、控件相对于父布局

Android基础之常用布局介绍
Android基础之常用布局介绍

     这种看起来就比较简单了, 属性值为 true 或 false

     android:layout_centerHrizontal                     水平居中

     android:layout_centerVertical                       垂直居中

     android:layout_centerInparent                     相对于父元素完全居中

     android:layout_alignParentBottom              贴紧父元素的下边缘

     android:layout_alignParentLeft                    贴紧父元素的左边缘

     android:layout_alignParentRight                  贴紧父元素的右边缘

     android:layout_alignParentTop                     贴紧父元素的上边缘

     扩展:接触过FrameLayout(帧布局)都知道,帧布局是一个控件盖在另一个控件上的,当然FrameLayout的限制太多,有时候我们需要两个控件重合的需求时,RelativeLayout也可以做到,如图,只需让它们处于同一个位置即可:

<pre name="code" class="html"><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >

    <Button android:text="12345678987654321" android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <Button android:text="55555" android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</LinearLayout>
           
Android基础之常用布局介绍

2.线性布局LinearLayout

     线性布局LinearLayout是最常用的布局之一,它可以把包含的子元素(View)排列成一列或者一行,即垂直方向或者水平方向,默认是水平方向,代码中方向可以通过setOrientation()方法设置,可以通过setGravity设置子元素的对齐方式,还可以通过子元素的weight属性设置子元素在LinearLayout中占的显示比重。

纯线性布局的缺点是很不方便修改控件的显示位置,所以开发中经常会 以 线性布局与相对布局嵌套的形式设置布局。

    一、下面展示线性布局的orientation属性:

Android基础之常用布局介绍

    水平排列horizontal:

Android基础之常用布局介绍

    垂直排列vertical:

Android基础之常用布局介绍

    二、weight(权重)属性

    LinearLayout里面最重要的属性之一就是weight(权重)了,它的意思是所占剩余屏幕宽(高)度的比例(注意:是剩余的比例),很多初学者直接将它理解为所占屏幕的比例,这种是错误的,接着看,你就会明白

    假设需求:有三个文本,高度全充满,宽度要做成1:2:3

    1、三个文本android:layout_width="0dp",用weight表示宽度,展示效果如图所示:

Android基础之常用布局介绍

    xml文件如下:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal">

    <TextView android:text="" android:layout_width="0dp"
        android:background="#f00"
        android:layout_height="match_parent"
        android:layout_weight="1"/>

    <TextView android:text="" android:layout_width="0dp"
        android:background="#0f0"
        android:layout_height="match_parent"
        android:layout_weight="2"/>

    <TextView android:text="" android:layout_width="0dp"
        android:background="#00f"
        android:layout_height="match_parent"
        android:layout_weight="3"/>

</LinearLayout>
           

    2、三个文本android:layout_width="wrap_content",用weight表示宽度,展示效果如图所示:

Android基础之常用布局介绍

    好像与上图一模一样,没错,你没有看错,确实是一样的这个时候我想你会说,是啊,就是这样啊,你说强调的剩余有什么用呢?不要急,再接着看,下面我们为第一个设置一个文本看一看,你就明白了:

Android基础之常用布局介绍

    代码如下:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal">

    <TextView android:text="11111111111111111111111111111" android:layout_width="wrap_content"
        android:background="#f00"
        android:layout_height="match_parent"
        android:layout_weight="1"/>

    <TextView android:text="" android:layout_width="wrap_content"
        android:background="#0f0"
        android:layout_height="match_parent"
        android:layout_weight="2"/>

    <TextView android:text="" android:layout_width="wrap_content"
        android:background="#00f"
        android:layout_height="match_parent"
        android:layout_weight="3"/>

</LinearLayout>
           

    是不是很吃惊,有时候你会怀疑自己的眼睛,原本1:2:3的画面怎么会变成这个样子,再仔细观察你发现第二个和第三个确实是2:3,只是第一个差别太大了,如果你把第一个文本所占的空间全部遮盖住你会发现什么呢,是不是遮盖后剩余的很像是1:2:3,这就是宽度设置为wrap_content与0dp的区别了,因为设置wrap_content控件本身会有宽度,weight属性只能共享剩下的宽度,第一个文本占得宽度越大,共享的宽度自然就越小了,再接着看,谜底就要出来了。

    3、三个文本android:layout_width="match_parent",用weight表示宽度,展示效果如图所示:

Android基础之常用布局介绍

    xml文件如下:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal">

    <TextView android:text="" android:layout_width="match_parent"
        android:background="#f00"
        android:layout_height="match_parent"
        android:layout_weight="1"/>

    <TextView android:text="" android:layout_width="match_parent"
        android:background="#0f0"
        android:layout_height="match_parent"
        android:layout_weight="2"/>

    <TextView android:text="" android:layout_width="match_parent"
        android:background="#00f"
        android:layout_height="match_parent"
        android:layout_weight="3"/>

</LinearLayout>
           

     这时候你还惊讶吗?是不是不敢相信自己的眼睛了,不要慌,这是事实,这里出现了一个大问题:原本应该1:2:3的页面完全的变样了,变成了2:1:0,第三个蓝色文本不见了,到了现在,你还相信你的weight表示所谓所占屏幕宽(高)的理论吗?

    下面,我们就用第三种结论来反向论证我们weight表示所谓所占剩余屏幕宽(高)的理论:

    1.屏幕宽度为match_parent,而我们设置了三个文本,则占用了3*match_parent,屏幕宽度剩余-2*match_parent

    2.我们的理论是共享剩余屏幕宽度,则红色所占宽度为:match_parent+(-2*match_parent)*1/(1+2+3)=(2/3)*match_parent;

    绿色所占宽度为:match_parent+(-2*match_parent)*2/(1+2+3)=(1/3)*match_parent;

    蓝色所占宽度为:match_parent+(-2*match_parent)*3/(1+2+3)=0*match_parent

    3,比例为(2/3)*match_parent:(1/3)*match_parent:0*match_parent=2:1:0

    由此,我们可以得出结论LinearLayout中weight属性表示所占剩余屏幕宽(高)的比例。

3、帧布局(FrameLayout):

    FrameLayout无疑是很简单的布局了。所有放在布局里的控件,都按照层次堆叠在屏幕的左上角。后加进来的控件覆盖前面的控件。在FrameLayout布局里,定义任何空间的位置相关的属性都毫无意义。控件自动的堆放在左上角,根本不听你的控制(所以说使用限制蛮大的,不过一般用RelativeLayout也可以做到这个效果)。

    我写一个demo,展示的是一层一层堆叠起来的图形,大家自然就明白了:

Android基础之常用布局介绍

    xml文件:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal">

    <TextView android:text=""
        android:layout_width="300dp"
        android:background="#000"
        android:layout_height="300dp" />

    <TextView android:text="" android:layout_width="250dp"
        android:background="#f00"
        android:layout_height="250dp" />

    <TextView android:text="" android:layout_width="200dp"
        android:background="#0f0"
        android:layout_height="200dp" />

    <TextView android:text="" android:layout_width="150dp"
        android:background="#00f"
        android:layout_height="150dp" />

    <TextView android:text="" android:layout_width="100dp"
        android:background="#fff"
        android:layout_height="100dp"/>
</FrameLayout>
           

     注意事项:

1 、各布局不要乱用其他布局的属性。比如把属于 AbsoluteLayout 布局的android:layout_x和android:layout_y用到 LinearLayout 布局或 RelativeLayout 布局,或者把 RelativeLayout 布局的 below ,toRightOf 等属性应用到其他布局中。这样做虽然不会报错,但这是白浪费感情的工作,根本达不到我们需要的效果。

2 、关于android:layout_width="match_parent"和android:layout_height="wrap_content" ,这是对每个布局宽和高的设置。wrap_content 可表示随着其中控件的不同而改变这个布局的宽度或高度,类似于自动设置宽和高,match_parent使布局填充整个屏幕,另外还有一种 fill_parent ,它本质上和 match_parent 一样,只是从 API  Level8 开始用match_parent替代。