Android ConstraintLayout详解

AndroidStudio2.2开始,就推出了一个牛逼的布局,ConstraintLayout,此布局像是一个升级版的RelativeLayout,但是功能比RelativeLayout强大许多,号称一层布局就可以搞定复杂页面。在AS2.2下还可以用拖拽控件的方式就行布局(设计师的福音),不过本篇不讲解拖拽控件的相关用法,主要讲解一些相关属性含义。
想学习拖拽控件设计ConstraintLayout的请点这里
Android官方教程在此
本文讲解参考这里,需自备梯子。

开始!

  • 相对位置这个相对位置的设置有点类似RelativeLayout的layout_toLeftOf、alignParentLeft等这些属性。
    ConstraintLayout一共支持相对位置的属性在此:
    layout_constraintLeft_toLeftOf
    layout_constraintLeft_toRightOf
    layout_constraintRight_toLeftOf
    layout_constraintRight_toRightOf
    layout_constraintTop_toTopOf
    layout_constraintTop_toBottomOf
    layout_constraintBottom_toTopOf
    layout_constraintBottom_toBottomOf
    layout_constraintBaseline_toBaselineOf
    layout_constraintStart_toEndOf
    layout_constraintStart_toStartOf
    layout_constraintEnd_toStartOf
    layout_constraintEnd_toEndOf拿第一个属性来说,layout_constraintLeft_toLeftOf=”@+id/id_first”,表示当前View的左边界与id_first的View的做边界对齐。其实这个属性翻译成中文就是:当前view的左边对齐与引用view的左边。
    例子:
 <Button android:id=&quot;@+id/buttonB&quot; ... app:layout_constraintLeft_toRightOf=&quot;@+id/buttonA&quot; />1 2 3 1 2 3 1 2 3 1 2 3 " data-snippet-id="ext.3190b6ad748f0e96e5cbd62a084f67f5" data-snippet-saved="false" data-codota-status="done">`&lt;Button android:id=&lt;span class="hljs-string">"@+id/buttonA"&lt;/span> &lt;span class="hljs-keyword">...&lt;/span> /&gt;
         &lt;Button android:id=&lt;span class="hljs-string">"@+id/buttonB"&lt;/span> &lt;span class="hljs-keyword">...&lt;/span>
                 app:layout_constraintLeft_toRightOf=&lt;span class="hljs-string">"@+id/buttonA"&lt;/span> /&gt;`

效果如下:
这里写图片描述

当然,这些属性也支持设置为对齐父布局的左右前后。

1 2 1 2 1 2 1 2 " data-snippet-id="ext.66574d68fbfbe560220fafc526a7805f" data-snippet-saved="false" data-codota-status="done">`&lt;Button android:id=&lt;span class="hljs-string">"@+id/buttonB"&lt;/span> &lt;span class="hljs-keyword">...&lt;/span>
                 app:layout_constraintLeft_toLeftOf=&lt;span class="hljs-string">"parent"&lt;/span> /&gt;`

这样,buttonB就依附在父布局的左边。类似Realitelayout的alignParentLeft。

  • margin属性这个属性没啥好说的,跟其他布局的margin属性差不多。支持的属性如下:
    Android:layout_marginStart
    android:layout_marginEnd
    android:layout_marginLeft
    android:layout_marginTop
    android:layout_marginRight
    android:layout_marginBottom
    这里写图片描述 注意:如上图,假如A紧贴父布局的左侧,B距离A 100dp,A设置为gone后,则B距离父布局的左侧100dp。
  • goneMargin属性这个布局比较有意思,还是拿上面的那副图做示例,假设我们现在有这样一个需求:假设A设置为gone,后,B需要距离父布局的左侧200dp,怎么办?这时候,goneMargin属性就派上用场啦,只要设置B的layout_goneMarginLeft=200dp即可。这样,A不为gone的时候,B距离A 100dp,A为gone时,B距离父布局左侧200dp。
    一共支持的属性如下:
    layout_goneMarginStart
    layout_goneMarginEnd
    layout_goneMarginLeft
    layout_goneMarginTop
    layout_goneMarginRight
    layout_goneMarginBottom
  • Centering positioning and bias ,设置居中或者按比例偏移。
    假设我们要设置一个控件居中怎么办?很简单,利用上面介绍过的属性就可以办到。
 <Button android:id=&quot;@+id/button&quot; ... app:layout_constraintHorizontal_bias=&quot;0.3&quot; app:layout_constraintLeft_toLeftOf=&quot;parent&quot; app:layout_constraintRight_toRightOf=&quot;parent/> </>1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 " data-snippet-id="ext.fa91acc62f5d2da7b193dcfae6657c0a" data-snippet-saved="false" data-codota-status="done">` &lt;android.support.constraint.ConstraintLayout &lt;span class="hljs-keyword">...&lt;/span>&gt;
             &lt;Button android:id=&lt;span class="hljs-string">"@+id/button"&lt;/span> &lt;span class="hljs-keyword">...&lt;/span>
                 app:layout_constraintHorizontal_bias=&lt;span class="hljs-string">"0.3"&lt;/span>
                 app:layout_constraintLeft_toLeftOf=&lt;span class="hljs-string">"parent"&lt;/span>
                 app:layout_constraintRight_toRightOf=&lt;span class="hljs-string">"parent/&gt; &lt;/&gt;&lt;/span>`

bias支持的属性如下:
layout_constraintHorizontal_bias
layout_constraintVertical_bias

  • ConstraintLayout本身支持minHeight、minWidht属性,没啥好说的。
  • 注意ConstraintLayout不支持match_parent属性,要用0dp代替,在加上设置特性的约束属性,即可实现match_parent的效果。
  • Ratio 设置宽高比。属性如下:app:layout_constraintDimensionRatio=””
    当前控件宽或高其一确定的话,可以使用ration属性,根据确定的宽或高确定另外高或宽的大小。
1 2 3 1 2 3 1 2 3 1 2 3 " data-snippet-id="ext.61bb115f4c457e5f98465a4b7d6d7cca" data-snippet-saved="false" data-codota-status="done">`&lt;span class="hljs-tag">&lt;&lt;span class="hljs-title">Button&lt;/span> &lt;span class="hljs-attribute">android:layout_width&lt;/span>=&lt;span class="hljs-value">"wrap_content"&lt;/span>
                   &lt;span class="hljs-attribute">android:layout_height&lt;/span>=&lt;span class="hljs-value">"0dp"&lt;/span>
                   &lt;span class="hljs-attribute">app:layout_constraintDimensionRatio&lt;/span>=&lt;span class="hljs-value">"1:2"&lt;/span> /&gt;&lt;/span>`

当前Button的width已经确定,height根据设置的比例=2×width
layout_constraintDimensionRatio接受的值是两个float类型的比例,代表的含义是width:height。
ration属性还支持这样设置:

1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 " data-snippet-id="ext.a36ae08c59e13d415c4b81a470c4cb1d" data-snippet-saved="false" data-codota-status="done">`&lt;span class="hljs-tag">&lt;&lt;span class="hljs-title">Button&lt;/span> &lt;span class="hljs-attribute">android:layout_width&lt;/span>=&lt;span class="hljs-value">"0dp"&lt;/span>
                   &lt;span class="hljs-attribute">android:layout_height&lt;/span>=&lt;span class="hljs-value">"0dp"&lt;/span>
                   &lt;span class="hljs-attribute">app:layout_constraintDimensionRatio&lt;/span>=&lt;span class="hljs-value">"H,16:9"&lt;/span>
                   &lt;span class="hljs-attribute">app:layout_constraintBottom_toBottomOf&lt;/span>=&lt;span class="hljs-value">"parent"&lt;/span>
                   &lt;span class="hljs-attribute">app:layout_constraintTop_toTopOf&lt;/span>=&lt;span class="hljs-value">"parent"&lt;/span>/&gt;&lt;/span>`

其中前面的字符H代表Height、W代表Width,谷歌官方的解释是:

In that case, you need to indicate which side should be constrained, by adding the letter W (for constraining the width) or H (for constraining the height) in front of the ratio

翻译过来就是说,W、H代表哪条边应该被约束。什么鬼?完全不理解。
还要经过我代码测试,勉强知晓了前面H、W的意思。上面示例代码的Button高已经确定,宽是高的十六分之九:9/16,如果前面设置位W的话,那么宽的大小是高的九分之十六:16/9倍。
_总结:假设比例设置为a:b ,如果前面是H,不论哪一边确定,另外一边的大小都是确定边的b/a倍;如果前面是W,不论哪一边确定,另外一边的大小都是确定边的a/b倍。_不知道谷歌是出于什么哲学思想,感觉像是个bug。

  • Chains 链状结构。看图如下:这里写图片描述
    Chain Style
    要想chain style生效,必须设置当前链方向的边为wrap_content,比如上面的水平链,宽设为wrap_content。还有就是控件要相互引用,比如A的右边依赖B的左边,B的左边依赖A的右边,都是设置。
    chain style设置在第一个控件上
    这里写图片描述
    即设置在head上。

    属性有两个:
    layout_constraintHorizontal_chainStyle
    layout_constraintVertical_chainStyle
    支持的值有三个:
    CHAIN_SPREAD:均与分布控件。
    CHAIN_SPREAD_INSIDE,同上,但是边上的控件不均匀分布。
    CHAIN_SPREAD_INSIDE:控件紧挨在一起。还可以通过bias属性设置偏移量。
    根据字面意思这三个属性好理解,效果如下:
    这里写图片描述

    Weighted chains:
    app:layout_constraintHorizontal_weight
    app:layout_constraintVertical_weight
    跟线性布局的weight差不多,layout_constraintHorizontal_weight需要设置width=0dp,控件的大小根据设置的weight比例进行设置。

    • Guideline
      Guideline是一条隐形的线,这条线可作为准线,根据此准线设置其他控件的位置。

<android.support.constraint.Guideline android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/guideline" app:layout_constraintGuide_begin="100dp" android:orientation="vertical"/>