一 背景
ConstraintLayout 是目前是android studio 2.2 以后的默認(rèn)根布局。 到目前為止,大家還是習(xí)慣常用的布局。同事先嘗試了下ConstraintLayout優(yōu)化布局層次,筆者也使用了下,發(fā)現(xiàn)確實(shí)比較好用。下面我們一起來(lái)試著使用布局吧~~
二 demo
來(lái)看下有個(gè)簡(jiǎn)單的布局是這個(gè)樣子的

其中文字‘金豆’ 左邊金色條是居中對(duì)齊文字一欄的。按傳統(tǒng)布局,這個(gè)簡(jiǎn)單的布局至少需要三層布局, 垂直方向和 單個(gè)水平方向。下面看下使用ConstraintLayout布局。
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="15dp"
android:layout_marginTop="10dp">
<ImageView
android:id="@+id/golden_beans_tips_icon"
android:layout_width="wrap_content"
android:layout_height="15dp"
android:scaleType="fitCenter"
android:src="?attr/skin_line_gold30_gift"
app:layout_constraintBottom_toBottomOf="@+id/golden_beans_tips"
app:layout_constraintTop_toTopOf="@+id/golden_beans_tips"
tools:src="@drawable/line_gold30_gift" />
<TextView
android:id="@+id/golden_beans_tips"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="20dp"
android:layout_marginLeft="5dp"
android:layout_marginTop="25dp"
android:importantForAccessibility="no"
android:text="@string/pay_unit"
android:textColor="?attr/skinT2"
android:textSize="@dimen/skin_textsize_l3"
app:layout_constraintLeft_toRightOf="@+id/golden_beans_tips_icon"
app:layout_constraintTop_toBottomOf="parent"
tools:textColor="@color/skin_t2" />
<TextView
android:id="@+id/golden_bean_number"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="25dp"
android:contentDescription="@{viewModel.goldenBeanDescription}"
android:text="12"
android:textColor="?attr/skinT2"
android:textSize="@dimen/mine_balance_text_size"
app:layout_constraintLeft_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/golden_beans_tips"
tools:text="12"
tools:textColor="@color/skin_t2" />
<TextView
android:layout_width="90dp"
android:layout_height="35dp"
android:layout_marginRight="15dp"
android:background="@drawable/bg_btn_mine_balance"
android:gravity="center"
android:text="@string/pay_money"
android:textColor="@color/skin_t7"
android:textSize="@dimen/skin_textsize_l4"
app:layout_constraintBottom_toBottomOf="@+id/golden_bean_number"
app:layout_constraintRight_toLeftOf="parent"
app:layout_constraintTop_toTopOf="@+id/golden_bean_number" />
</android.support.constraint.ConstraintLayout>
其實(shí),ConstraintLayout 寫起來(lái)比較方便,與RelativeLayout非常相似。 首先我們看下 要保證垂直方向的順序布局。 如果沒(méi)使用ConstraintLayout前,需要使用垂直方向的LinearLayout 或RelativeLayout。 我們的ConstraintLayout 怎樣保證的呢?
app:layout_constraintTop_toBottomOf="@+id/golden_beans_tips"
一行代碼,是不是跟RelativeLayout類似。 同理 我們要保持文本 ‘12’ 和按鈕‘充值’ 水平方向
app:layout_constraintTop_toTopOf="@+id/golden_bean_number"
是不是很簡(jiǎn)單。那怎么保證第一行的金色條icon 居中對(duì)齊 文本 ‘金豆’呢?
app:layout_constraintBottom_toBottomOf="@+id/golden_beans_tips"
app:layout_constraintTop_toTopOf="@+id/golden_beans_tips"
即對(duì)齊文本‘金豆’的上下邊緣, 這里有一個(gè)比較形象的說(shuō)法,就是constraintXXX_toXXXOf 表示對(duì)于id 對(duì)本view的拉力。這里上下方向拉力一致,所以文本居中了。那么我們的相對(duì)布局其實(shí)就有 4 * 2 8種方式:
layout_constraintLeft_toLeftOf
layout_constraintLeft_toRightOf
layout_constraintRight_toLeftOf
layout_constraintRight_toRightOf
layout_constraintTop_toTopOf
layout_constraintTop_toBottomOf
layout_constraintBottom_toTopOf
layout_constraintBottom_toBottomOf
三 進(jìn)一步升級(jí)打怪
看了上面的一個(gè),我們有個(gè)需求的ui是這樣子的

當(dāng)然,這個(gè)只是布局的一小塊,你可以看成listView 的item 優(yōu)化布局的層次還是比較重要的。
你可能會(huì)說(shuō) what a shell !??! ConstraintLayout 來(lái)布局很簡(jiǎn)單呀,實(shí)際上,你使用上面的約束,想一層布局搞定,貌似搞不定。來(lái),看下我們的布局代碼
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:bind="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="25dp"
android:layout_marginLeft="15dp"
android:layout_marginRight="15dp"
android:maxLines="1"
android:ellipsize="end"
android:id="@+id/title"
android:textColor="?attr/skinT2"
bind:layout_constraintLeft_toLeftOf="parent"
bind:layout_constraintRight_toLeftOf="@+id/more"
bind:layout_constraintHorizontal_bias="0"
android:textSize="@dimen/skin_textsize_l3"
android:text="情感故事情情感故事情感故情感情感情感故事情感故情感情感感故情感情感"
tools:text="情感故事情情感故事情感故情感情感情感故事情感故情感情感感故情感情感"
tools:textColor="@color/skin_t2" />
<ImageView
android:id="@+id/more"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="15dp"
bind:layout_constraintRight_toRightOf="parent"
bind:layout_constraintTop_toTopOf="@+id/title"
bind:layout_constraintBottom_toBottomOf="@+id/title"
android:src="?attr/skin_btn_arrow_stroke"
tools:src="@drawable/btn_arrow_stroke" />
</android.support.constraint.ConstraintLayout>
我們看
bind:layout_constraintLeft_toLeftOf="parent"
bind:layout_constraintRight_toLeftOf="@+id/more"
使用這兩行代碼之后文本 已經(jīng)在 icon 更多左邊,但是文本是居中的,看起來(lái)是這樣

原因是parent左邊和右邊more的拉力是相同的,所以文本寬度不夠時(shí),居中了。那問(wèn)題來(lái)了,我想讓文本居左怎么辦?
bind:layout_constraintRight_toLeftOf去不掉,是需要保證在icon的左邊,那怎么辦呢?
app:layout_constraintHorizontal_bias="0"
layout_constraintHorizontal_bias 表示水平偏向, 取值 0 到 1, 即在兩個(gè)拉力中偏左為0, 偏右為1 ,默認(rèn)就是0.5, 也可以看成左右間距比例。相似的還有垂直方向layout_constraintVertical_bias
恩,ui需求又來(lái)了,比較常見(jiàn)的如, 水平三個(gè)按鈕,我想等分水平的,這里不再贅述,ConstraintLayout中類似LinearLayout weight的屬性就ok。
app:layout_constraintHorizontal_weight="1"
四 更多
還有幾個(gè)重要的屬性,本文不一一列出,前面的基本需求都無(wú)壓力了。
app:layout_constraintHorizontal_chainStyle 鏈?zhǔn)降?br>
以及 按寬高比布局屬性 app:layout_constraintDimensionRatio。