ConstraintLayout-進階的RelativeLayout
近日伴隨著Android Studio 2.2的正式推送,最大的亮點是布局的藍圖模式以及與之配套的ConstraintLayout關(guān)注度一下子高了起來.
ConstraintLayout,翻譯過來,可以叫約束布局,其子view就是通過一個個屬性的約束,來決定自己的位置,大小,而傳統(tǒng)的RelativeLayout也類似,所以可以看成是RelativeLayout的一種進化版版本,屬性布局用法相對RelativeLayout來說較為復(fù)雜,但是當你熟悉之后你會愛上它的.
眾所周知,Android APP的布局復(fù)雜度會極大的影響程序的流暢度,傳統(tǒng)的ViewGroup用的最多的就是RelativeLayout與LineaLayout.
一般能用RelativeLayout替換LineaLayout就替換,因為LinearLayout雖然簡單,但是會加深層級.
而有時候卻不得不使用LinearLayout,在于LinearLayout有一個layout_weight屬性,可以設(shè)置LinearLayout的ChildView按照一定的比例布局,這是RelativeLayout做不到的.
ConstraintLayout的其他的屬性和用法基本與RelativeLayout一致,如果對RelativeLayout比較熟悉的童鞋很容易上手,而ConstraintLayout最大的優(yōu)點便是可以添加比例的控制.
準備工作
- 下載Android Studio2.2
- 新建一個項目,打開MainActivity布局,并切換到Design(左下角)設(shè)計視圖
- 選中l(wèi)ayout根目錄,右鍵,Convert轉(zhuǎn)換,將layout轉(zhuǎn)換為ConstraintLayout為根目錄的layout
初次轉(zhuǎn)換會提示你沒有 ConstraintLayout,問你是否下載,直接選擇下載即可,等下載好了會自動轉(zhuǎn)換
-
也可以直接在Module的gralde配置里添加
dependencies { compile 'com.android.support.constraint:constraint-layout:1.0.0-alpha8' }
藍圖介紹
- 普通視圖
- 藍圖
- 普通視圖和藍圖同在
- 關(guān)閉/打開布局的約束
- 關(guān)閉/打開自動為View添加約束
- 添加導(dǎo)航線
- 查看布局的警告/錯誤
基本約束屬性
前面說了, ConstraintLayout是RelativeLayout的進化版,如果RelativeLayout的子view沒有設(shè)置任何基本屬性,則置于左上角,ConstraintLayout同理.
ConstraintLayout基本屬性的值可以是某個控件的id,也可以是"parent",簡單的概括就是top,bottom,left,right,baseline.
以bottm為例
約束屬性值為id時對照表
約束屬性 | RelativeLayout屬性 |
---|---|
layout_constraintBaseline_toBaselineOf | layout_alignBaseline |
layout_constraintBottom_toBottomOf | layout_alignBottom |
layout_constraintBottom_toTopOf | layout_above |
layout_constraintEnd_toEndOf | layout_alignEnd |
layout_constraintEnd_toStartOf | layout_toStartOf |
layout_constraintLeft_toLeftOf | layout_alignLeft |
layout_constraintLeft_toRightOf | layout_toRightOf |
layout_constraintRight_toRightOf | layout_alignRight |
layout_constraintRight_toLeftOf | layout_toLeftOf |
layout_constraintStart_toStartOf | layout_alignStart |
layout_constraintStart_toEndOf | layout_toStartOf |
layout_constraintTop_toTopOf | layout_alignTop |
layout_constraintTop_toBottomOf | layout_below |
約束屬性值等于parent
當基本屬性值為parent時,必須成對出現(xiàn)才有意義,即top與bottom,left與right,start與end成對.
在使用RelativeLayout的時候,假設(shè)子View設(shè)置了屬性,則子View會置于底部
layout_alignParentBottom="true"
而對約束布局的子Viuew設(shè)置,是沒有任何效果的,因為parent屬性必須成對出現(xiàn)
layout_constraintBottom_toBottomOf="parent"
如果設(shè)置成對屬性,會發(fā)現(xiàn)控件在設(shè)置的方向上居中了,也達不到置于底部的效果
這時候前面介紹的功能派上用場了
ConstraintLayout最大的優(yōu)點便是可以添加比例的控制
比例屬性閃亮登場
layout_constraintHorizontal_bias="0.4"
layout_constraintVertical_bias="0.6"
這兩個屬性接受浮點型,是一個比例,數(shù)值在0-1之間,如不寫這屬性,默認為0.5
點擊左下角切換的Design,再點擊Button選中這個控件,右邊欄會出現(xiàn)約束屬性圖
簡單介紹一下這個屬性圖
- 箭頭向里 表示控件的寬度/高度是適應(yīng)內(nèi)容的,彈簧狀 表示控件是寬度/高度是具體數(shù)值
- 上下兩個0表示控件的上下margin是0
- 小球50這個數(shù)值表示在垂直方向上,上下的比例是0.5:0.5
鼠標拖動小球,上下移動會發(fā)現(xiàn)數(shù)值,控件垂直方向上的位置都跟著改變.拖動到20,切換到代碼,會發(fā)現(xiàn)代碼新增了一個屬性,此時控件的上下比例是:0.8:0.2
layout_constraintVertical_bias="0.8"
假設(shè)要達到layout_alignParentBottom="true"的效果,只需要加上top,bottom約束,并設(shè)置layout_constraintVertical_bias="1.0"即可
控件大小比例屬性
app:layout_constraintDimensionRatio="1:2"
除了上述介紹的控件相對于parent位置的比例外,子view還可以控制自身的寬高比
上述例子是比把控件的寬高比設(shè)置為1:2
這個屬性生效需要以下條件:left,right,top听皿,bottom 四條邊都需要約束,其中bottom的約束可以用baseline代替士复。
寬/高有且只有一個是0dp.
如果都是0dp的則會不會生效,因為控件如果上下都有約束,并把高度設(shè)置為0,控件的高度會充滿父控件,寬度同理,從而導(dǎo)致控件鋪滿整個父控件
creator迷之屬性
app:layout_constraintBaseline_creator="12"
app:layout_constraintTop_creator="12"
app:layout_constraintBottom_creator="12"
app:layout_constraintLeft_creator="12"
app:layout_constraintRight_creator="12"
creator接受整型屬性值,但該屬性在 1.0.0-alpha8 版本暫時未有任何作用,查看源碼發(fā)現(xiàn),ConstraintLayout只是對改屬性值進行了接受,但是沒有做任何處理,相信在后續(xù)版本會新增其功能
else if(attr != styleable.ConstraintLayout_Layout_layout_constraintLeft_creator && attr != styleable.ConstraintLayout_Layout_layout_constraintTop_creator && attr != styleable.ConstraintLayout_Layout_layout_constraintRight_creator && attr != styleable.ConstraintLayout_Layout_layout_constraintBottom_creator && attr != styleable.ConstraintLayout_Layout_layout_constraintBaseline_creator) {
Log.w("ConstraintLayout", "Unknown attribute 0x" + Integer.toHexString(attr));
}
Guideline導(dǎo)航線
app:layout_constraintGuide_begin="50dp"
app:layout_constraintGuide_end="50dp"
app:layout_constraintGuide_percent="50"
介紹導(dǎo)航線之前,先想一下,根據(jù)上面對ConstraintLayout的介紹,要你布置一個菜單控件,菜單欄每一項均分屏幕寬度,按照以前使用LinearLayout,會把每一個子view的weight設(shè)置為1,則均分了屏幕寬度
<LinearLayout>
<View/>
<View/>
<View/>
</LinearLayout>
而使用ConstraintLayout則會發(fā)現(xiàn)前面介紹的比例,是相對parent來說的,如果要均分屏幕寬度,必須借助透明的分割線來布局
<ConstraintLayout>
<View,右邊約束分割線1/>
<分割線1,距離左邊33%/>
<View,左邊約束分割線1,右邊約束分割線2/>
<分割線2,距離左邊66%/>
<View,左邊約束分割線2/>
</ConstraintLayout>
而這個分割線其實谷歌已經(jīng)幫我們寫好了,就是Guideline.藍圖介紹中,6對應(yīng)的就是添加導(dǎo)航線.切換到藍圖模式,點擊6,就可以添加一個水平/垂直的導(dǎo)航線
添加垂直導(dǎo)航線
注意:圖中的導(dǎo)航線有一個向左的箭頭模式,除了這個模式還有向右,百分比模式.如果導(dǎo)航線是水平的,還會有上下箭頭.
點擊小球即可切換模式
Guideline屬性對照表
屬性 | 箭頭 |
---|---|
layout_constraintGuide_begin | 左/上 |
layout_constraintGuide_end | 右/下 |
layout_constraintGuide_percent | 百分比 |
Guideline屬性值
Guideline本身對于用戶來說是不可見的,所以其寬高的值沒有任何意義,也不起作用.
<android.support.constraint.Guideline
android:id="@+id/guideline"
android:layout_width="wrap_content"http://無意義
android:layout_height="511dp"http://無意義
android:orientation="vertical"http://決定這是一條水平導(dǎo)航線還是垂直導(dǎo)航線
app:layout_constraintGuide_percent="0.333"http://決定導(dǎo)航線的位置
/>
此時再添加一條比例為0.666的導(dǎo)航線,即可三等分屏幕(點擊圖片可查看詳細代碼)
總結(jié)
ConstraintLayout完美的結(jié)合了RelativeLayout與LinearLayout的特點,減少了布局的層級,展現(xiàn)了其強大的功能.
除了上述介紹到的功能之外,ConstraintLayout的子view被設(shè)置為GONE后,依賴這個view的約束會自動繼承這個子view的約束,從而保證布局不會錯亂.而且還可以單獨設(shè)置控件隱藏/顯示時的外邊距.
藍圖模式讓view與view之間的依賴關(guān)系更加的清晰明了,還可以快速設(shè)置屬性值.
有人認為拖動控件必將成為主流,而博主實際體驗,當控件非常復(fù)雜的時候,非常多的約束也會讓人眼花繚亂.
其實最好的方式還是用藍圖與代碼結(jié)合的方式,在創(chuàng)建,快速設(shè)置依賴關(guān)系,以及設(shè)置屬性的時候,使用藍圖模式,在細微的調(diào)整的時候,使用代碼模式.