一直以来,都有写博客的打算,最近实在是懒散惯了,还是应该动动手,内容可能有瑕疵,希望各位大神踊跃发言,提点建议,不胜感激。
在 android 中我们常用的布局方式有这么几种:RelativeLayout,LinearLayout,FrameLayout,TableLayout,AbsoluteLayout,当然有些布局已经不再常用,例如TableLayout,只介绍前三个,还有其他布局如GridLayout,TabLayout等等,有兴趣自行研究。
1.RelativeLayout ( 相对布局 ):
顾名思义,相对布局,就是相对于其他控件的布局,相信我这样说,大家很好的理解,然而我们都知道。在这里,我们需要理解这么一个常识,一个控件,给定它的宽高属性之后,如果不指定它的位置,那么它就是排列在手机屏幕上的左上角的位置,也就是说,一个控件的默认位置就是在屏幕的左上角,当你指定它在布局中的位置有效时,它才会排列在一个新的位置上。
相对布局分为两个方面:一是控件相对于其他控件,二是控件相对于父布局。
一、控件相对于其他控件
常用属性有以下这些:属性值必须为 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 离某元素上边缘的距离
二、控件相对于父布局
这种看起来就比较简单了, 属性值为 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>
2.线性布局LinearLayout
线性布局LinearLayout是最常用的布局之一,它可以把包含的子元素(View)排列成一列或者一行,即垂直方向或者水平方向,默认是水平方向,代码中方向可以通过setOrientation()方法设置,可以通过setGravity设置子元素的对齐方式,还可以通过子元素的weight属性设置子元素在LinearLayout中占的显示比重。
纯线性布局的缺点是很不方便修改控件的显示位置,所以开发中经常会 以 线性布局与相对布局嵌套的形式设置布局。
一、下面展示线性布局的orientation属性:
水平排列horizontal:
垂直排列vertical:
二、weight(权重)属性
LinearLayout里面最重要的属性之一就是weight(权重)了,它的意思是所占剩余屏幕宽(高)度的比例(注意:是剩余的比例),很多初学者直接将它理解为所占屏幕的比例,这种是错误的,接着看,你就会明白
假设需求:有三个文本,高度全充满,宽度要做成1:2:3
1、三个文本android:layout_width="0dp",用weight表示宽度,展示效果如图所示:
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表示宽度,展示效果如图所示:
好像与上图一模一样,没错,你没有看错,确实是一样的这个时候我想你会说,是啊,就是这样啊,你说强调的剩余有什么用呢?不要急,再接着看,下面我们为第一个设置一个文本看一看,你就明白了:
代码如下:
<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表示宽度,展示效果如图所示:
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,展示的是一层一层堆叠起来的图形,大家自然就明白了:
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替代。