Android Development for Beginners -Building Layouts Part B

前言

Lesson 1中包含三大部分内容:

  • 如何根据需求选择对应的View(展示图片:ImageView 展示文本:TextView)
  • 如何修改View的样式(字体颜色、图片的缩放裁剪)
  • 接下来就来讲讲这第三小节的内容:如何将多个View按照需求在屏幕上进行摆放

引入

市面上每个应用的界面都是由许多的View组合而成的(QQ 微信 微博)那么这就涉及到整个布局中的View如何去进行摆放

ViewGroup

ViewGroup能够把View摆放在特定的位置(上or下or中……)

通过例子说明:

上次课中的例子都是只对单独的某个View作说明

对单独的某个View作说明

尝试着再拷贝一份TextView元素放到下面,你会发现出现了错误


错误写法

注意:根View有且仅有一个,想要放置多个View时根View必须为一个ViewGroup

ViewGroup也属于View的一种,是屏幕上的一块矩形,ViewGroup包含于View,View包含ViewGroup

如图

图中可以看到ViewGroup同样有宽高、背景颜色等属性 不难理解因为ViewGroup属于View
当然ViewGroup通常都是透明的即用户看不见的
可以把ViewGroup理解为View的容器

一个View包含着其他的View,前者为父View,后者叫子View,后者之间称兄弟View

? 看图提问 ?

提问

答案在文章底部公布

到目前为止,我们已经知道了 想要放置多个View在屏幕上就必须把它们放到ViewGroup里

ViewGroup的类型

ViewGroup有很多种,每种ViewGroup都有其包含视图的规则,先介绍两种最最最常用的ViewGroup

LinearLayout(线性布局)

LinearLayout就是一个ViewGroup
规则:子视图称线性排列故称线性布局,所谓线性即水平竖直

线性布局

理论结束,看代码如何编写

线性布局代码

ViewGroup使用单独的关闭标签,子视图书写在ViewGroup的开始标签和结束标签之间
LinearLayout的方向通过其属性: android:orientation 指定,
其值有二: vertical竖直方向、horizontal水平方向

特别注意:如果你不知道orientation属性是干嘛的,那你会怎么办?问别人? 千万别,你应该直接去百度或谷歌一下,肯定有你要的答案。 这里我想告诉大家的是要学会通过搜索引擎去解决问题。这种事以后还多着呢!

照着上图给你的代码去XMLV练习一下,尝试着增加一些子视图和更改它们的排列方向。

命名空间:XML命名空间声明,使用命名空间来指定所有的android属性,为什么使用android:前缀就是这个原因,特指示android系统自带的属性,其实前面也说过我们是可以自定义属性的,自定义属性时,前缀就是我们自定义的某个文本而非android了。 android: 是用来区分这些都是Android系统自带的属性
所以务必在根视图的开始标签中加上XML命名空间的声明

LinearLayout的宽高

  • xxdp(固定宽高 xx具体指某个数值)
  • 当内容的大小大于视图所设置的宽高时,会显示不全(被切掉一部分)
  • wrap_content (包裹内容)
  • 视图大小 == 内容大小
  • match_parent(匹配父布局)
  • 无论视图宽高为多少,视图与父布局均等宽/高


线性布局宽高
![](http://upload-images.jianshu.io/upload_images/1869092-200cb5e22a7eb4ce.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

注意一种场景: 当前线性布局方向为horizontal(竖直方向),若有其中一个子视图的高度为match_parent,那么这个子视图将把它下面的子视图都顶出父布局之外(不可见)自己占据父布局剩下的高度,同理宽度亦然。

线性布局 - 屏幕适配

运行Android系统的设备千千万万,设备的屏幕大小、屏幕分辨率各式各样。
由此就会产生一个问题: 应用在不同设备上所显示的效果千差万别!
就如下图所示,分别在纵向放置、横向放置、大屏设备上显示的效果会不尽人意,三个TextView都挤到左上角了,这对于使用大屏设备的用户来说是尤为不人性化 也就是所说的用户体验极差。



需求 如果想要让这三个TextView无论在什么设备上都平均在屏幕的上中下的位置需要怎么做呢?

尝试用我们学过的知识:

  • 每个TextView使用固定的高度均分屏幕大小?
  • 只能针对某一个分辨率的屏幕,不能适配所有的屏幕大小
  • 使用wrap_content?
  • 包裹内容就如上图所示
  • 使用match_parent?
  • 匹配父元素会将剩余的兄弟师傅挤出父布局之外(无法看见)

以上做法都不能实现适配所有的设备,肿么办?问人? 不! 问人之前先百度/谷歌!!!
或者可以直接去安卓官方文档查找LinearLayout的属性 相信你能自己解决!

Layout Weight (布局权重)

布局权重:在线性布局中给各个子视图按比例分配空间,注意:仅在LinearLayout中有权重的概念

权重的使用
步骤一:

  • 当父布局(线性布局)的方向为水平方向(horizontal)时
    • android:layout_width="0dp" 把宽度设置为0dp
  • 当父布局(线性布局)的方向为竖直方向(vertical)时
    • android:layout_height="0dp" 把高度设置为0dp

步骤二:

  • android:layout_weight="xx" 给每个子视图分配权重 xx为某个数值

权重越大,分配的空间越大


实现均分只需分配相等的权重即可

![Uploading QQ截图20160401172435_550530.png . . .]


同理大家可以自己去实现水平方向的均分

来些应用例子


微信输入框布局

线性布局的东西到此结束!

RelativeLayout(相对布局)

相对布局相对于线性布局而言,更加灵活,方便。

规则:子视图与父布局(父视图)相对排列,或 子视图之间相对排列

代码如何编写?

子视图与父布局(父视图)相对排列

      android:layout_alignParentTop="true"            <!--与父布局的上边对齐-->
      android:layout_alignParentBottom="true"         <!--与父布局的下边对齐-->
      android:layout_alignParentLeft="true"           <!--与父布局的左边对齐-->
      android:layout_alignParentRight="true"          <!--与父布局的右边对齐-->
      android:layout_centerInParent="true"            <!--(水平竖直都)居中于父布局-->
      android:layout_centerHorizontal="true"          <!--水平居中于父布局-->
      android:layout_centerVertical="true"            <!--竖直居中于父布局-->
            
      <!--上述属性值默认为false-->

示例

根据图片上的文字位置,想想要用哪些个属性实现
<?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">
    <!--默认在左上角-->
    <TextView
        android:text="左上"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?android:textAppearanceLarge" />
    <TextView
        android:text="右上"
        android:layout_alignParentRight="true"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?android:textAppearanceLarge" />
    <TextView
        android:text="左中"
        android:layout_centerVertical="true"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?android:textAppearanceLarge" />
    <TextView
        android:text="右中"
        android:layout_alignParentRight="true"
        android:layout_centerVertical="true"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?android:textAppearanceLarge" />
    <TextView
        android:text="左下"
        android:layout_alignParentBottom="true"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?android:textAppearanceLarge" />
    <TextView
        android:text="右下"
        android:layout_alignParentRight="true"
        android:layout_alignParentBottom="true"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?android:textAppearanceLarge" />
    <TextView
        android:text="上中"
        android:layout_centerHorizontal="true"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?android:textAppearanceLarge" />
    <TextView
        android:text="下中"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?android:textAppearanceLarge" />
    <TextView
        android:text="正中"
        android:layout_centerInParent="true"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?android:textAppearanceLarge" />
</RelativeLayout>

子视图之间相对排列

  android:layout_toLeftOf="@id/xxx"       <!--在id为xxx的视图的左侧-->
  android:layout_toRightOf="@id/xxx"      <!--在id为xxx的视图的右侧-->
  android:layout_below="@id/xxx"          <!--在id为xxx的视图的下方-->
  android:layout_above="@id/xxx"          <!--在id为xxx的视图的上方-->

  android:layout_alignTop="xxx"           <!--上边缘与id为xxx的视图对齐-->
  android:layout_alignBottom="xxx"        <!--下边缘与id为xxx的视图对齐-->
  android:layout_alignLeft="@id/xxx"      <!--左边缘与id为xxx的视图对齐-->
  android:layout_alignRight="xxx"         <!--右边缘与id为xxx的视图对齐-->
  
  

说明: 每个视图都可以设置id属性作为唯一标识

  android:id="@+id/xxx"              <!--@+id  表示声明一个id属性-->

  android:layout_toLeftOf="@id/xxx"  <!--@id   引用某个已声明的id属性对应的视图,在id为xxx的视图左边-->

示例

相对布局示例效果图
<?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">
    <Button
        android:id="@+id/btn_up"
        android:text="上"
        android:layout_above="@id/btn_center"
        android:layout_alignLeft="@id/btn_center"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?android:textAppearanceLarge"/>
    <Button
        android:id="@+id/btn_center"
        android:text="中"
        android:layout_toRightOf="@id/btn_left"
        android:layout_above="@id/btn_down"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?android:textAppearanceLarge"/>
    <Button
        android:id="@+id/btn_down"
        android:text="下"
        android:layout_alignLeft="@id/btn_center"
        android:layout_alignParentBottom="true"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?android:textAppearanceLarge"/>
    <Button
        android:id="@+id/btn_left"
        android:text="左"
        android:layout_alignTop="@id/btn_center"
        android:layout_alignParentLeft="true"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?android:textAppearanceLarge"/>
    <Button
        android:id="@+id/btn_right"
        android:text="右"
        android:layout_toRightOf="@id/btn_center"
        android:layout_alignTop="@id/btn_center"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?android:textAppearanceLarge"/>

    <Button
        android:id="@+id/btn_hand"
        android:text="拳"
        android:layout_alignBottom="@id/btn_foot"
        android:layout_toLeftOf="@id/btn_foot"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?android:textAppearanceLarge"/>
    <Button
        android:id="@+id/btn_foot"
        android:text="脚"
        android:layout_alignBottom="@id/btn_center"
        android:layout_alignParentRight="true"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?android:textAppearanceLarge"/>
</RelativeLayout>

代码结合上面的属性说明与效果图对比学习。

再来看一个常见的例子,QQ好友列表项的布局



动手写一下布局吧,相信你可以的

<?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="wrap_content">

   <ImageView
       android:id="@+id/iv_icon"
       android:src="@mipmap/ic_launcher"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content" />
    <TextView
        android:id="@+id/tv_name"
        android:text="树懒"
        android:layout_toRightOf="@id/iv_icon"
        android:textAppearance="?android:textAppearanceLarge"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
    <TextView
        android:id="@+id/tv_text"
        android:text="[在线] 时间冲淡了我的咖啡"
        android:textColor="@android:color/darker_gray"
        android:layout_toRightOf="@id/iv_icon"
        android:layout_below="@id/tv_name"
        android:textAppearance="?android:textAppearanceMedium"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
    <TextView
        android:id="@+id/tv_signal"
        android:text="4G"
        android:layout_alignParentRight="true"
        android:textColor="@android:color/darker_gray"
        android:textAppearance="?android:textAppearanceMedium"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
</RelativeLayout>

代码显示效果如下图

是不是感觉View都挤到一起了很难看 - -!

不足: 这些View都紧挨着父布局的边缘,这样显示给用户的感觉非常的不好。

怎么样给视图周围留出一些空白呢?

Padding & Margin (内边距 & 外边距)

用图说话

内外边距的区别

根据上图可以清楚的看到Padding 和Margin之间的区别

  • Padding 内边距:View与View的内容之间的边距
  • Margin 外边距 : 整个View与父布局之间的边距

在实际开发中由于视图的背景一般都为透明,所以二者之间看起来并无差别

android:padding="xxdp"              <!--上下左右的内边距为xxdp-->
android:paddingTop="xxdp"           <!--上边的内边距为xxdp-->
android:paddingBottom="xxdp"        <!--下边的内边距为xxdp-->
android:paddingLeft="xxdp"          <!--左边的内边距为xxdp-->
android:paddingRight="xxdp"         <!--右边的内边距为xxdp-->

android:layout_margin="xxdp"          <!--上下左右的外边距为xxdp-->
android:layout_marginTop="xxdp"       <!--上边的外边距为xxdp-->
android:layout_marginBottom="xxdp"    <!--下边的外边距为xxdp-->
android:layout_marginLeft="xxdp"      <!--左边的外边距为xxdp-->
android:layout_marginRight="xxdp"     <!--右边的外边距为xxdp-->

据此修改上面写的QQ好友列表项的代码如下

<?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="wrap_content"
   android:padding="8dp">     <!-- 给整个布局添加内边距 -->

  <ImageView
      android:id="@+id/iv_icon"
      android:src="@mipmap/ic_launcher"
      android:layout_marginRight="8dp"  
      android:layout_width="wrap_content"
      android:layout_height="wrap_content" />    <!-- 给图片添加右边的外边距 -->
   <TextView
       android:id="@+id/tv_name"
       android:text="树懒"
       android:layout_toRightOf="@id/iv_icon"
       android:textAppearance="?android:textAppearanceLarge"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content" />
   <TextView
       android:id="@+id/tv_text"
       android:text="[在线] 时间冲淡了我的咖啡"
       android:textColor="@android:color/darker_gray"
       android:layout_toRightOf="@id/iv_icon"
       android:layout_below="@id/tv_name"
       android:textAppearance="?android:textAppearanceMedium"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content" />
   <TextView
       android:id="@+id/tv_signal"
       android:text="4G"
       android:layout_alignParentRight="true"
       android:textColor="@android:color/darker_gray"
       android:textAppearance="?android:textAppearanceMedium"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content" />
</RelativeLayout>
效果图

至于边距应该设置为多少合适,参照Meterial Design 设计规范:
http://wiki.jikexueyuan.com/project/material-design/

规范中推荐为8dp的倍数。

END

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

推荐阅读更多精彩内容