这篇就对LinearLayout、RelativeLayout、自定义ViewGroup、FrameLayout、TableLayout、AbsoluteLayout六种布局进行详细的讲解。

1.LinearLayout布局

线性布局,两种排法:

  • 从左到右
    android:orientation=”horizontal”
  • 从上到下
    android:orientation=”vertical”
    具体上图


一个竖向的大LinearLayout嵌套着两个小LinearLayout,第一个小LinearLayout为横向,第二个小LinearLayout为竖向。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="250dp"
android:orientation="horizontal">
<TextView
android:layout_width="96dp"
android:layout_height="match_parent"
android:background="#b2dfdb" />
<TextView
android:layout_width="96dp"
android:layout_height="match_parent"
android:background="#80cbc4" />
<TextView
android:layout_width="96dp"
android:layout_height="match_parent"
android:background="#4db6ac" />
<TextView
android:layout_width="96dp"
android:layout_height="match_parent"
android:background="#26a69a" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="68dp"
android:background="#b2dfdb" />
<TextView
android:layout_width="match_parent"
android:layout_height="68dp"
android:background="#80cbc4" />
<TextView
android:layout_width="match_parent"
android:layout_height="68dp"
android:background="#4db6ac" />
<TextView
android:layout_width="match_parent"
android:layout_height="68dp"
android:background="#26a69a" />
</LinearLayout>
</LinearLayout>

2.RelativeLayout布局

参考其他控件进行布局,默认为父控件。
有三种类型的属性:

  • 属性值是true或false

    • android:layout_centerHrizontal 水平居中
    • android:layout_centerVertical 垂直居中
    • android:layout_centerInparent 相对于父元素完全居中。
    • android:layout_alignParentBottom 位于父元素的下边缘
    • android:layout_alignParentTop 位于父元素的上边缘
    • android:layout_alignParentLeft 位于父元素的左边缘
    • android:layout_alignParentRight 位于父元素的右边缘
  • 属性值是”@id/*“
    • android:layout_below 在某元素的下方
    • android:layout_above 在某元素的上方
    • andorid:layout_toRightOf 在某元素的右方
    • android:layout_toLeftOf 在某元素的左方
    • android:layout_alignBottom 和某元素下方对齐
    • android:layout_alignTop 和某元素上方对齐
    • android:layout_alignRight 和某元素右方对齐
    • android:layout_alignLeft 和某元素左方对齐
  • 属性值是数值
    • android:layout_marginLeft 离某元素左边缘的距离
    • android:layout_marginRight 离某元素右边缘的距离
    • android:layout_marginTop 离某元素上边缘的距离
    • android:layout_marginBottom 离某元素下边缘的距离

各取一个来写例子,如图。


注意

  • 如果没有定义左右,那么默认在左边,如果没有定义上下,默认在上边。
  • 相同位置,新定义的元素会覆盖旧的元素。例:1被2覆盖了。
  • 4只定义了在父元素的下部,左右没有定义,于是默认就在左边了。
  • android:layout_below,在某元素的下部并不意味着就一定是紧随某元素,只是在下部的默认位置。例如:5是在3的下部,但是是在下部的默认左边。
  • 6为下边缘对齐3,7为marginLeft=150dp。
  • 8为多个属性共同定义的结果。首先是在3的右部,然后是垂直居中,然后marginLeft=100dp得到最后位置。

代码如下:

<?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"
android:orientation="vertical"> <TextView
style="@style/btn_relative" android:text="1" /> <TextView
style="@style/btn_relative" android:text="2" /> <TextView
android:id="@+id/txt_center"
style="@style/btn_relative" android:layout_centerInParent="true" android:text="3" /> <TextView
style="@style/btn_relative" android:layout_alignParentBottom="true" android:text="4" /> <TextView
style="@style/btn_relative" android:layout_below="@id/txt_center"
android:background="#d0d9ff" android:text="5" /> <TextView
style="@style/btn_relative" android:layout_alignBottom="@+id/txt_center" android:text="6" /> <TextView
style="@style/btn_relative" android:layout_marginLeft="150dp" android:text="7" /> <TextView
style="@style/btn_relative" android:layout_centerVertical="true"
android:layout_marginLeft="100dp"
android:layout_toRightOf="@id/txt_center" android:text="8" />
</RelativeLayout>

3.MyLayout布局(自定义ViewGroup)

自定义布局主要是重写两个方法:

  • onMeasure() 这个是写自定义容器的大小。
  • onLayout() 这个是写子元素的布局。
    我自己写了一个自定义布局,是顺序填充会延对角线进行排列。

3.1onMeasure()

 @Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
/**
* 获得此ViewGroup上级容器为其推荐的宽和高,以及计算模式
*/
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int sizeWidth = MeasureSpec.getSize(widthMeasureSpec);
int sizeHeight = MeasureSpec.getSize(heightMeasureSpec); // 计算出所有的childView的宽和高
measureChildren(widthMeasureSpec, heightMeasureSpec);
/**
* width和height是当wrap_content时使用的属性。
*/
int width = 0;
int height = 0;
int cCount = getChildCount();
int cWidth = 0;
int cHeight = 0;
/**
* 在这里计算当wrap_content时,布局的大小。
*/
for (int i = 0; i < cCount; i++) {
View childView = getChildAt(i);
cWidth = childView.getMeasuredWidth();
cHeight = childView.getMeasuredHeight();
width += cWidth;
height += cHeight;
}
/**
* 如果是wrap_content设置为我们计算的值
* 否则:直接设置为父容器计算的值
*/
setMeasuredDimension((widthMode == MeasureSpec.EXACTLY) ? sizeWidth
: width, (heightMode == MeasureSpec.EXACTLY) ? sizeHeight
: height); }

首先要说一下布局计算模式,即最后的EXACTLY。一共有三种计算模式:

  • MeasureSpec.EXACTLY:精确尺寸,相当于具体数值和match_parent。
  • MeasureSpec.AT_MOST:最大尺寸,相当于 warp_content。
  • MeasureSpec.UNSPECIFIED:未指定尺寸,这种情况不多,一般用于AdapterView。

最后的设定大小时,如果是精确尺寸就是用sizeWidth即获取的尺寸,如果是最大尺寸就是要我们自己计算的那个尺寸了。
onMeasure()最主要的功能就是计算wrap_content的尺寸设置尺寸
我将这个方法称为“建画布”,先建了画布才能在上面绘图嘛。

3.2 onLayout()

@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
int cCount = getChildCount(); /**
* 遍历所有childView根据其宽和高,以及margin进行布局
*/
for (int i = 0; i < cCount; i++) {
View childView = getChildAt(i);
r = l + childView.getMeasuredWidth();
b = t + childView.getMeasuredHeight();
childView.layout(l, t, r, b);
l += childView.getMeasuredWidth();
t += childView.getMeasuredHeight();
}
}

这个方法的作用是设置摆放子元素的位置。其中onLayout()传入的l、t、r、b分别是这样

  • l,t分别对应子元素左上角的left,top坐标
  • r,b分别对应子元素右下角的right,bottom坐标

并且可以使用childview.getMeasuredWidth()和childView.getMeasureHeight()得到子元素的宽和高。
这样就可以来对每个子元素进行布局了。
我称这个方法为“定位置”。定完位置后那么子元素就被放到了我们想要的地方。
这样一个自定义ViewGroup就可以使用了。
xml文件如下:

<?xml version="1.0" encoding="utf-8"?>
<com.example.layoutdemo.MyLayout.MyLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
> <TextView
android:layout_width="50dp"
android:layout_height="50dp"
android:background="#b2dfdb" /> <TextView
android:layout_width="50dp"
android:layout_height="50dp"
android:background="#80cbc4" /> <TextView
android:layout_width="50dp"
android:layout_height="50dp"
android:background="#4db6ac" /> <TextView
android:layout_width="50dp"
android:layout_height="50dp"
android:background="#26a69a" /> </com.example.layoutdemo.MyLayout.MyLayout>

最后效果如图:

4.FrameLayout布局

帧布局,这个布局的特点是从左上角开始,后面的会覆盖前面的控件。
代码如下:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="100dp"
android:textColor="#9c27b0"
android:text="第一层"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="80dp"
android:textColor="#e91e63"
android:text="第二层"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="60dp"
android:textColor="#e51c23"
android:text="第三层"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="40dp"
android:textColor="#5677fc"
android:text="第四层"/>
</FrameLayout>

实际效果如下:

5.TableLayout布局

表格布局。
它遵循着以下结构:

<TableLayout>
<TableRow>
<!-在这里填充第一行的元素->
</TableRow>
<TableRow>
<!-在这里填充第二行的元素->
</TableRow>
</TableLayout>

还有几个重要属性:

  • 写在TableLayout中的属性

    • android:stretchColumns 设置第几列为伸展(0表示第一列)
    • android:shrinkColumns 设置第几列为收缩
    • android:collapseColumns 设置第几列为隐藏
  • 写在TableRow里的控件里的属性
    • android:layout_column 设置控件在第几列
    • android:layout_span 设置控件能跨多少列
    • android:gravity 设置控件的排列方式,可以水平居中,水平靠左,水平靠右,垂直居中,垂直靠右,垂直靠左

代码如下:

<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:collapseColumns="2"
android:shrinkColumns="1"
android:stretchColumns="0"> <TableRow
>
<TextView android:text="我是伸展的第一列" /> <TextView android:text="我是收缩的第二列" /> <TextView android:text="我被隐藏了" />
</TableRow> <TableRow>
<TextView android:text="我可以伸展的很长很长很长长" /> <TextView android:text="我可以收缩,我可以变的很深很深很深" /> <TextView android:text="我被隐藏了T_T" />
</TableRow> <TableRow>
<TextView
android:layout_column="1"
android:text="我要在第2列" />
</TableRow> <TableRow>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_column="0"
android:layout_span="2"
android:text="我要 跨 两 列" />
</TableRow>
</TableLayout>

最后效果如下:

如果想要设置两个一个并排显示的,可以参考下面的代码:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/daylimit_content_alter"
android:layout_width="match_parent"
android:layout_height="match_parent" > <TableLayout
android:layout_width="fill_parent"
android:layout_height="50dp"
android:layout_alignParentBottom="true"
android:collapseColumns="2" > <TableRow android:gravity="center_horizontal" > <Button
android:layout_weight="0.5"
android:onClick="CopyBtn"
android:text="复制" /> <Button
android:layout_weight="0.5"
android:onClick=""
android:text="返回" />
</TableRow>
</TableLayout> </RelativeLayout>

效果图:

6.AbsoluteLayout布局

绝对布局,极力不推荐,官方已经舍弃。
定义两个控件左上角坐标轴
android:layout_xandroid:layout_y来控制位置。

<?xml version="1.0" encoding="utf-8"?>
<AbsoluteLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"> <TextView
style="@style/btn_relative" android:text="1" /> <TextView
style="@style/btn_relative"
android:layout_x="60dp"
android:layout_y="60dp"
android:text="1" /> <TextView
style="@style/btn_relative"
android:layout_x="160dp"
android:layout_y="160dp"
android:text="1" /> <TextView
style="@style/btn_relative"
android:layout_x="260dp"
android:layout_y="260dp"
android:text="1" />
</AbsoluteLayout>

最后效果如下:

原文连接:http://blog.csdn.net/u013254061/article/details/52512146

【Android】Android六种布局详解的更多相关文章

  1. android:TableLayout表格布局详解

    http://blog.csdn.net/justoneroad/article/details/6835915 这篇博文包括的内容:1.TableLayout简介2.TableLayout行列数的确 ...

  2. Android 之 TableLayout 布局详解

    TableLayout简介 •简介 Tablelayout 类以行和列的形式对控件进行管理,每一行为一个 TableRow 对象,或一个 View 控件. 当为 TableRow 对象时,可在 Tab ...

  3. [置顶] Android系统五大布局详解Layout

    我们知道Android系统应用程序一般是由多个Activity组成,而这些Activity以视图的形式展现在我们面前,视图都是由一个一个的组件构成的.组件就是我们常见的Button.TextEdit等 ...

  4. Android系统五大布局详解Layout

    我们知道Android系统应用程序一般是由多个Activity组成,而这些Activity以视图的形式展现在我们面前, 视图都是由一个一个的组件构成的.组件就是我们常见的Button.TextEdit ...

  5. Android学习之基础知识六—Android四种布局详解

    一.Android基本布局 布局是一种可以放置多个控件的容器,它可以按照一定规律调整内部控件的位置,而且布局内部除了可以放置控件外,还可以放置布局,实现多层布局嵌套.布局和控件.布局和布局之间的关系如 ...

  6. Android LinearLayout线性布局详解

    为了更好地管理Android应用的用户界面里的各组件,Android提供了布局管理器.通过使用布局管理器,Android应用图形用户界面具有良好的平台无关性.推荐使用布局管理器来管理组件的分布.大小, ...

  7. Android开发重点难点1:RelativeLayout(相对布局)详解

    前言 啦啦啦~博主又推出了一个新的系列啦~ 之前的Android开发系列主要以完成实验的过程为主,经常会综合许多知识来写,所以难免会有知识点的交杂,给人一种混乱的感觉. 所以博主推出“重点难点”系列, ...

  8. Android布局详解之一:FrameLayout

      原创文章,如有转载,请注明出处:http://blog.csdn.net/yihui823/article/details/6702273 FrameLayout是最简单的布局了.所有放在布局里的 ...

  9. Android 布局详解

    Android 布局详解 1.重用布局 当一个布局文件被多处使用时,最好<include>标签来重用布局. 例如:workspace_screen.xml的布局文件,在另一个布局文件中被重 ...

随机推荐

  1. 设置Linux中的Mysql不区分表名大小写

    1. MySQL数据库的表名在Linux系统下是严格区分大小写的,在Windows系统下开发的程序移植到Linux系统下,如果程序中SQL语句没有严格按照大小写访问数据库表,就可能会出现找不到表的错误 ...

  2. 恶性循环中的永生bug,可以说是相当写实了

    恶性循环中的永生bug,可以说是相当写实了

  3. 35个让人惊讶的CSS3动画效果

    1. Pure CSS Coke Can 2. Colorful Clock 3. jQuery DJ Hero 4. Animated Pricing Column 5. Slick jQuery  ...

  4. iOS9 Error Domain=NSURLErrorDomain Code=-1022 App Transport Security (ATS)

    iOS 9在HTTP 访问时会出错  iOS9 Error Domain=NSURLErrorDomain Code=-1022 这时需要修改info.plist 文件 在Info.plist中添加N ...

  5. 自定义控件之万能Repeater源码

    using System.ComponentModel; using System.Web.UI; [assembly: TagPrefix("Jinlong.Control", ...

  6. LintCode: Identical Binary Tree

    C++ /** * Definition of TreeNode: * class TreeNode { * public: * int val; * TreeNode *left, *right; ...

  7. PAT《数据结构学习与实验指导》实验项目集 2-09 2-10 2-11 2-12 2-13

    pat 2-09 装箱问题模拟 #include<cstdio> #include<set> #include<vector> using namespace st ...

  8. (转)C#中Invoke的用法 一

    在用.NET Framework框架的WinForm构建GUI程序界面时,如果要在控件的事件响应函数中改变控件的状态,例如:某个按钮上的文本原先叫“打开”,单击之后按钮上的文本显示“关闭”,初学者往往 ...

  9. Bootstrap定制开发

    Bootstrap作为目前很受欢迎的前端框架,越来越多的网站开始使用基于Bootstrap框架进行开发. 1.定制开发方法 (1)Bootstrap定制开发可以使用LESS和Grunt实现定制化 (2 ...

  10. bat判断进程是否存在

    setlocal enabledelayedexpansion @echo offcd /d D:\work\tool\nginx-1.13.7 set hasit=nofor /F "to ...