Android开发-UI布局

Android中所有的UI(用户界面)都是使用View和ViewGroup对象建立的,View是一个可以将一些信息绘制在屏幕上并与用户产生交互的对象ViewGroup是一个可以包含多个的View和ViewGroup的容器,用来定义UI布局。

Android提供了一系列View和ViewGroup子类,开发者可以灵活的组合使用它们来完成界面布局、界面元素绘制和用户交互等工作

开发者还可以选择性地继承一些系统提供的View,来定义View,把自己定义的界面元素显示给用户。

Android的UI开发使用层次模型来完成,一般都是在一个ViewGroup中嵌套多层ViewGroup,每层中含有任意数目的View,但最好不要超过十层

常用的布局

  • LinearLayout——线性布局

  • RelativeLayout——相对布局

  • FrameLayout——帧布局

  • TableLayout——表格布局

  • AbsoluteLayout——绝对布局

  • GridLayout——网格布局

布局定义方式

定义UI布局的最常用的方法是使用XML布局文件,如同HTML一样,XML为布局提供了一种可读的结构。XML中的每个元素都是,View或ViewGroup的子孙的对象组成的树。树根是一个ViewGroup对象,所有的叶节点都是View对象,树的分支节点都是ViewGroup对象。

Android中是ViewGroup可以嵌套包含很多View以及ViewGroup对象,ViewGroup是View的子类。

Android UI屏幕适配

  • 屏幕尺寸:指屏幕的对角线长度,单位为英寸,1英寸== 2.45cm

  • 屏幕分辨率:指水平和垂直方向的像素点个数,单位px,1px== 1像素点,一般以垂直像素*水平像素,例如 1920 * 1080

  • 屏幕像素密度:指每英寸上的像素点数,单位是dpi,dpi:dot per inch。屏幕像素密度与屏幕尺寸有关。

  • px:像素点,构成图像的最小单位

  • dip:device independent pixels(设备独立像素),也是密度无关像素。以160dpi为基准,1dip=1px。

  • dp:与dip相同。

  • sp:专门用于字体的像素单位,一般定义为偶数。

LinearLayout (线性布局)

1. vertical / horizontal

使用android:orientation= "vertical/horizontal"定义排列方向

//linearlayout.xml

<?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" >
    
    <!--线性布局是按照水平和垂直排布的,默认是水平排布的
        orientation:用来指定当前线性布局排布的方向
        horizontal:水平
        vertical:垂直-->

</LinearLayout>

2. margin / padding

属性 含义
android:layout_marginXXX(XXX:left/tpo) 设置该控件距离左、上边界的距离
android:paddingXXX(XXX:left/top) 设置控件内部距离控件边缘的距离
  • 区分:
    margin:表示控件距离其他或者屏幕边缘的间距。---外边距
    padding:表示控件的内部内容距离控件边缘的间距。---内边距
    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="30dp"
        android:text="Button" />
        <!--wrap_content :代表包裹内容,适合内容大小
            match_parent :父类大小
            layout_margn是指组件距离父窗体的距离,
            padding是指组件中的内容距离组件边缘的距离-->

3. gravity / layout_gravity

属性 含义
android:gravity 用于设置该View内部内容的对齐方式
android:layout_gravity 用于设置该View在其父类中的对齐方式
  • 注意:如果线性布局的排布方式为水平,那么layout_gravity在水平方向上就不起作用,只有在垂直方向上起作用,反之亦然。

  • 可选值包括:
    left、right、top、bottom、center、horizon
    center_vertical、center_horizontal
    bottom\center_horizontal(使用\组合使用)

4. layout_weight (LinearLayout特有属性)

LinearLayout特有属性,android:layout_weight,表示比重,可实现百分比布局,如果控件为 match_parent,则layout_weight的值与占比重反相关,即:其值越大,占用比例越小,如果控件为 wrap_content,则对比重判断则为正相关,即其值越小,占用的比例越小。

<?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" 
    android:weightSum="3">
    <!--总的权重-->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#00ff00"
        android:layout_weight="2">
        <!--绿色区,权重为2-->
    </LinearLayout>
    
        <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#ff0000"
        android:layout_weight="1">
        <!--红色区,权重为1-->
    </LinearLayout>
</LinearLayout>
  • 注意:
    若在一个页面中,有一个有权重控件,和一个无权重的控件,系统会先给无权重的控件分配空间后,才会得到需要百分比的空间大小,进行百分比划分。权重布局只存在于LinearLayout中,其余布局无效。

RelativeLayout(相对布局)

RelativeLayout(相对布局):按照控件相互之间的相对位置来确定,RelativeLayout中往往需要定义每一个控件的资源ID。

1. 常用属性

常用属性 含义
layout_alineParentXXX(XXX:方向) 对齐方式
android:layout_marginXXX 外部间距
android:paddingXXX(XXX:left/top) 内部间距
android:layout_centerVertical 垂直居中
android:layout_centerHorizontal 水平居中
android:layout_centerInParent 父类的中部

注意:layout_widthlayout_height是在平面图形中不可或缺的两个属性,任何图形需要显示都需要宽和高。

2. android:layout_toRightOf(在某个控件的右方)

<Button
    android:id="@+id/button1"
    android:layout_weight="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginTop="30dp"
    android:layout_marginLeft="30dp"
    android:padding="20dp"
    android:text="Button"/>
    <!--@+id:表示系统本来不存在的对应ID值,其方向性的单词可以更换。
        以上Button可作为参照物-->
<Button
    android:layout_weight="wrap_content"
    android:layout_height="wrap_content"
    android:layout_toRightOf="@id+button1"
    android:layout_alingnBottom="@+id/button1"/>    
    <!--在控件的右方、底部-->

3. anignBaseline (基准线对齐)

4. layout_below (在XX的下方)

  • 注意:

    针对相对布局而言,一般不会过多给定很多想关联的属性,否则耦合性就会大大增加。相对布局的重点在于理解控件id,在相对布局中的控件一般都存在id属性,+id表示是系统中本来不存在的对应的id值,需要将这个id值添加到系统中,@id表示从系统中去除已经添加好的id。

TableLayout (表格布局)

TableLayout属于行和列形式的管理控件,每行为一个TableRow对象也可以是一个View对象。在TableRow中还可以继续添加其他控件,每添加一个子控件就成一列,TableLayout不会生成边框。

TableLayout是继承至LinearLayout,即TableLayout有LinearLayout的属性(见上文)。同时也有自己的特有属性:

XML属性名 说明
android:collapseColumns 设置指定的列为collapse,该列会被隐藏
android:shrinkColumns 设置指定的列为shrinkable,该列的宽度进行收缩,自适应父类容器的大小
android:stretchColumns 设置指定的列为stretch,该列会被拉伸,填充满表格的空白区域
<?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:stretchColumns="0,1,2"
    android:shrinkColumns="0" 
    android:collapseColumns="2">
    <!--stretch拉伸1,2,3列,
        shrinkable收缩第一列,
        collapse隐藏第一列
        拉伸后收缩时因为,如果第一列内容过多,会覆盖第二三列,
        因此要收缩第一列,以显示所有内容-->
    
    <TableRow
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <!--此处Table可不设定宽高值,系统自动给定-->
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:padding="5dp"
            android:text="姓名"/>
        <!--TableLayout是LinearLayout的子类,可设置gravity、padding等属性-->
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="性别"/>
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="电话"/>
     </TableRow>
     
     <TableRow
        android:layout_width="match_patent"
        android:layout_height="wrap_content"
        android:"right">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginRight="30dp"
            android:text="总计:100"/>
     </TableRow>
     <!--此TableRow未遵循此表格布局-->
</TableLayout>

FrameLayout (帧布局)/ AbsoluteLayout (绝对布局)

FrameLayout(帧布局)默认是按左上角(0,0)开始排布,在帧布局下的每一个控件都是以画面的形式进行呈现,最开始定义的控件出现在最下方,最后定义的控件出现在最上方,一般用于手机联系人的导航显示字母、帧动画等内容。

<?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" >
    <TextView 
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#00ff00"
        android:text="你好"/>
    <TextView 
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_margin="30dp"
        android:background="#ff0000"
        android:text="页面"/>

</FrameLayout>

AbsoluteLayout(绝对布局),又叫做坐标布局,可以直接指定子元素的绝对位置,这种布局简单、直观性强。由于手机屏幕尺寸差别较大,使用绝对定位适应性会比较差,不推荐使用。一般用于固定屏幕手机。

属性 含义
android:layout_x 确定X坐标,以左上角为顶点
android:layout_y 确定Y坐标,以左上角为顶点
  • 注意:若不设置layout_x和layout_y,那么他们的默认值是(0,0)他们会出现在左上角。

GridLayout (网格布局)

GridLayout(网格布局)是在android4.0版本以上出现的布局,可以实现并行和并列的效果。

常用属性 含义
android:layout_columnSpan 扩展列的数目
android:layout_rowSpan 扩展行的数目
android:layout_gravity 填充方式
columnCount 定义存在多少列
rowCount 定义存在多少行
  • 注意:

    GridLayout与TableLayout有什么不同?

    TableLayout定义TableRow来呈现内容,GridLayout可以直接定义控件来使用,并且TableLayout不可以合并行或列。

计算器页面的实现

计算器页面.jpg
<?xml version="1.0" encoding="utf-8"?>
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" 
    android:columnCount="4">
<!--使用columnCount定义一共4列-->
    <!--放置按键-->
    <Button 
        android:id="@+id/num1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="1"/>

    <Button 
        android:id="@+id/num2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="2"/>
        
    <Button 
        android:id="@+id/num3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="3"/>
        
     <Button 
        android:id="@+id/chu"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="/"/>
        
    <Button 
        android:id="@+id/num4"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="4"/>

    <Button 
        android:id="@+id/num5"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="5"/>
        
    <Button 
        android:id="@+id/num6"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="6"/>
        
     <Button 
        android:id="@+id/cheng"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="*"/>

    <Button 
        android:id="@+id/num7"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="7"/>

    <Button 
        android:id="@+id/num8"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="8"/>
        
    <Button 
        android:id="@+id/num9"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="9"/>
        
     <Button 
        android:id="@+id/jian"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="-"/>

     <Button 
        android:id="@+id/num0"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_columnSpan="2"
        android:layout_gravity="fill"
        android:text="0"/>
    <!--columnSpan合并两列gravity填充整个区域-->
    <Button 
        android:id="@+id/dian"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="."/>
        
    <Button 
        android:id="@+id/jia"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_rowSpan="2"
        android:layout_gravity="fill"
        android:text="+"/>
        
     <Button 
        android:id="@+id/deng"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_columnSpan="3"
        android:layout_gravity="fill"
        android:text="="/>
</GridLayout>

Android UI开发分类

  1. 界面布局开发——定义界面的布局
  2. 控件开发——定义单个界面元素
  3. AdapterView与Adapter开发——列表显示(适配器的开发)
  4. UI组件开发——对话框、通知、菜单等
  5. 自定义View、图形图像和动画——通过代码,自行绘制界面。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,907评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,987评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,298评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,586评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,633评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,488评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,275评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,176评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,619评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,819评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,932评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,655评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,265评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,871评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,994评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,095评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,884评论 2 354

推荐阅读更多精彩内容