约束布局:开篇

随着Android Studio2.3正式版本的发布,约束布局(ConstraintLayout)也进入了1.0.1正式版,是时候进入安卓开发布局的新阶段了。


约束布局的概念第一次接触是在iOS开发的学习当中,苹果官方将约束布局叫做AutoLayout,但最终的实现其实就是约束布局。严格来讲,称为约束布局更为合适。

苹果官方在iOS5版本中引入了Storyboard方式实现使用拖拽方式完成布局,Storyboard中文可以翻译为故事板。这个名称取的非常有意思,而且还带有一些文艺色彩,开发一款APP其实恰好就是你给使用者讲的一个有意思的故事。虽然Storyboard已经推出了很久,却一直没有完全被大家所接受。普遍的一个论点认为:Storyboard在多人开发协作的时候将导致维护起来非常麻烦,因为Storyboard的xml可读性非常差,通过拖拉产生的改变导致xml的变化不计其数,这在多人开发的过程中无疑是灾难性的。但其实官方没有明确说明的是,Storyboard是可以同时使用多个的。比如,每一个功能模块使用一个Storyboard,每一个人负责一个模块,这就有效地避免了多人共同维护一个Storyboard的问题。尽管如此,由于前期的一些误解,导致中国iOS开发圈依然有大量的程序员使用代码进行约束布局。我想,这大约是苹果官方不愿意看到的吧!

言归正传,回到安卓的约束布局。

为了保证约束布局更便于理解,安卓官方引入了很多新的概念。但很多人一看到概念就会头晕脑胀。因此,本篇我们不讲任何理论和概念,具体的概念和理论留到最后一个章节讲解。

理解ConstraintLayout

约束布局的意思其实很简单,就是通过一系列的限制,让某个控件的位置实现唯一确定,这就是约束布局的核心思想。这样做的一个好处就是,避免了控件的无限制嵌套,减少过度绘制问题。看下面一个形象的例子:



假设这是一个垂直放置的矩形面板,这只可爱的小猫距离垂直边缘距离20m,距离水平边缘30m,这样在一个平面内,小猫的位置就唯一确定了。无论面板如何变化,他在面板里面的位置都是唯一确定的。距离垂直边缘距离20m和距离水平边缘30m这两个条件其实就是两个约束,学过基础数学的同学都知道在二维空间通过一个二维坐标(x,y)可以确定唯一的点,就是这个道理。

这个数学知识也告诉我们:要想唯一确定某个物体的位置,在水平和垂直方向必须至少各有一个约束条件。

约束布局的基础理论体系就建立在上面这个简单的数学知识之上,下面来实际操作一下,看一看安卓的约束布局是否设计的够简单,能否与iOS的自动布局相媲美。

实现一个简单的登录页面

添加依赖

dependencies {
    ...
    compile 'com.android.support.constraint:constraint-layout:1.0.1'
   ...
}

Note:推荐使用Android Studio 2.3,创建安卓工程会默认添加这个依赖,并且在创建约束布局的时候会给予友好的提示。

Let's get started

要实现这样一个布局,首先确定一个控件的绝对位置,其他控件可以以这个控件作为基点,来实现绝对定位。这里我们选择[用户名]这个TextView ,添加如下约束:


    <TextView
        android:layout_width="50dp"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        android:layout_marginTop="20dp"
        android:layout_marginLeft="10dp"
        android:textSize="16dp"
        android:textColor="@color/yaHei"
        android:text="@string/username"
        android:gravity="right"
        android:id="@+id/text_username"/>

这里的意思,其实可以通过英文意思去理解一下,其实是给TextView添加了两个约束:

  • TextView的顶部与父布局的顶部对齐
  • TextView的左边和父布局的左边对齐
    这两个约束分别作用在x和y方向,已经可以实现TextView位置的唯一确定。最后,通过添加margin就实现如上图的效果,接下来来确定用户名输入框,依然很简单,看下面一段xml:
  <EditText
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        app:layout_constraintBaseline_toBaselineOf="@id/text_username"
        app:layout_constraintLeft_toRightOf="@id/text_username"
        app:layout_constraintRight_toRightOf="parent"
        android:layout_marginLeft="10dp"
        android:layout_marginRight="10dp"
        android:textSize="16dp"
        android:textColor="@color/yaHei"
        android:hint="@string/input_username_please"/>

这里对EditText添加了三个约束:

  • EditText保持和上面的TextView基线对齐
  • EditText的左侧和TextView的右侧对齐
  • EditText的右侧和父布局对齐

这三个约束也保证了EditText位置的唯一确定,实现了如上图所示的效果。其他两个控件使用类似的方式实现了位置的唯一确定,这里就不赘述了,大家可以去我的Github进行Clone阅读。

小结

这篇文章只是简单地让大家了解了一下安卓最新推荐使用的ConstraintLayout的基本用法,没有涉及到任何相关的概念,因为我害怕一堆的概念一定会吓跑一批不敢去尝试新鲜事物的同学。因此,我希望大家在不了解概念的前提下看看约束布局使用起来是否非常简单,是否值得一试。

扩展

这不就是相对布局吗?

一定会有很多人产生这样的感觉。的确,相对布局可以实现其中的部分功能,可在很多场景中,相对布局是无法实现的。比如:基线对齐,两个控件的宽度按照一定的比例约束,单个控件的宽高也可以按照比例显示等等这些场景都是相对布局无法做到的。ConstraintLayout试图打造一个万能布局,换而言之,原来所学的五种布局(LinearLayout,FrameLayout,RelativeLayout,TableLayout,GridLayout)都可以舍弃了,可以完全使用这一个布局来实现所有的复杂布局,这是安卓官方的设计初衷。

这种布局有什么好处?

一定会有人有这样的疑问,有人甚至会想,如果布局较为复杂,满屏的约束会不会让人感到混乱。首先,上面的描述中我已经说了约束布局的第一个好处,就是:我们终于可以不用再记那么多布局了,仅仅使用这一个布局方式就可以实现所有复杂的布局。这一点iOS程序员体现的非常明显,最初的iOS开发是直接写死多少像素的,使用逐帧的方式布局。所以,你可以看到iOS程序员常常对一个像素非常敏感,原因就在于此。后面由于iOS设备越来越多,单一的逐帧布局已经无法满足需要,这种场景下约束布局应运而生。而到现在为止,这种布局iOS同学已经用了好几年,他们从来不需要去了解其他的布局方式,这就是约束布局的伟大之处。

第二个更屌的地方就是:也许拖拉一下我们就完成了布局。上面有提到,iOS官方推荐使用Storyboard实现自动布局,这种方式就是拖拉的典型代表。iOS同学已经享用了这种便利好几年,安卓同学终于拨开云雾见青天了。这个部分的讲解我们放到最后,和概念一起讲,前期我们一直使用xml实现布局。

约束布局可以嵌套吗?

应该有部分同学会有这样的疑问,答案是:当然可以。约束布局是继承自ViewGroup,实现了根据约束条件完成布局的逻辑(其实这并不简单)。所以,嵌套是一定可以的,如果你有需要嵌套约束布局才能完成的UI,大胆去做吧。

约束布局的性能如何?

其实,约束布局的诞生,从某种层面来说就是为了解决安卓布局不断嵌套的问题,减少过度绘制,避免过度绘制的开销。如果设计优良,在使用复杂布局时,毫无疑问,约束布局的性能是要高于其他布局方式的。所以,未来开发过程中,我推荐大家使用约束布局。

最佳的学习资料

https://developer.android.com/reference/android/support/constraint/ConstraintLayout.html
https://github.com/googlesamples/android-ConstraintLayoutExamples

这篇文章的Git代码地址:https://github.com/yuanhoujun/ConstraintLayoutSamples ,欢迎大家下载学习,后期的关于约束布局的讲解代码依然会放到这个仓库里面。

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

推荐阅读更多精彩内容