ConstraintLayout-進階的RelativeLayout

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
Paste_Image.png
  • 初次轉(zhuǎn)換會提示你沒有 ConstraintLayout,問你是否下載,直接選擇下載即可,等下載好了會自動轉(zhuǎn)換

  • 也可以直接在Module的gralde配置里添加

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

藍圖介紹

Paste_Image.png
  1. 普通視圖
  2. 藍圖
  3. 普通視圖和藍圖同在
  4. 關(guān)閉/打開布局的約束
  5. 關(guān)閉/打開自動為View添加約束
  6. 添加導(dǎo)航線
  7. 查看布局的警告/錯誤

基本約束屬性

前面說了, ConstraintLayout是RelativeLayout的進化版,如果RelativeLayout的子view沒有設(shè)置任何基本屬性,則置于左上角,ConstraintLayout同理.

ConstraintLayout基本屬性的值可以是某個控件的id,也可以是"parent",簡單的概括就是top,bottom,left,right,baseline.

以bottm為例

Paste_Image.png

約束屬性值為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è)置的方向上居中了,也達不到置于底部的效果

Paste_Image.png

這時候前面介紹的功能派上用場了

ConstraintLayout最大的優(yōu)點便是可以添加比例的控制

比例屬性閃亮登場

layout_constraintHorizontal_bias="0.4"
layout_constraintVertical_bias="0.6"

這兩個屬性接受浮點型,是一個比例,數(shù)值在0-1之間,如不寫這屬性,默認為0.5

點擊左下角切換的Design,再點擊Button選中這個控件,右邊欄會出現(xiàn)約束屬性圖

Paste_Image.png

簡單介紹一下這個屬性圖

  1. 箭頭向里 表示控件的寬度/高度是適應(yīng)內(nèi)容的,彈簧狀 表示控件是寬度/高度是具體數(shù)值
  2. 上下兩個0表示控件的上下margin是0
  3. 小球50這個數(shù)值表示在垂直方向上,上下的比例是0.5:0.5

鼠標拖動小球,上下移動會發(fā)現(xiàn)數(shù)值,控件垂直方向上的位置都跟著改變.拖動到20,切換到代碼,會發(fā)現(xiàn)代碼新增了一個屬性,此時控件的上下比例是:0.8:0.2

layout_constraintVertical_bias="0.8"
Paste_Image.png

假設(shè)要達到layout_alignParentBottom="true"的效果,只需要加上top,bottom約束,并設(shè)置layout_constraintVertical_bias="1.0"即可

Paste_Image.png

控件大小比例屬性

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)航線

Paste_Image.png

添加垂直導(dǎo)航線

Paste_Image.png

注意:圖中的導(dǎo)航線有一個向左的箭頭模式,除了這個模式還有向右,百分比模式.如果導(dǎo)航線是水平的,還會有上下箭頭.

點擊小球即可切換模式

Paste_Image.png

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)整的時候,使用代碼模式.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市共苛,隨后出現(xiàn)的幾起案子判没,更是在濱河造成了極大的恐慌蜓萄,老刑警劉巖隅茎,帶你破解...
    沈念sama閱讀 216,651評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件澄峰,死亡現(xiàn)場離奇詭異,居然都是意外死亡辟犀,警方通過查閱死者的電腦和手機俏竞,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,468評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來堂竟,“玉大人魂毁,你說我怎么就攤上這事〕鲟冢” “怎么了席楚?”我有些...
    開封第一講書人閱讀 162,931評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長税稼。 經(jīng)常有香客問我烦秩,道長,這世上最難降的妖魔是什么郎仆? 我笑而不...
    開封第一講書人閱讀 58,218評論 1 292
  • 正文 為了忘掉前任只祠,我火速辦了婚禮,結(jié)果婚禮上扰肌,老公的妹妹穿的比我還像新娘抛寝。我一直安慰自己,他們只是感情好曙旭,可當我...
    茶點故事閱讀 67,234評論 6 388
  • 文/花漫 我一把揭開白布盗舰。 她就那樣靜靜地躺著,像睡著了一般桂躏。 火紅的嫁衣襯著肌膚如雪钻趋。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,198評論 1 299
  • 那天沼头,我揣著相機與錄音爷绘,去河邊找鬼。 笑死进倍,一個胖子當著我的面吹牛土至,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播猾昆,決...
    沈念sama閱讀 40,084評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼陶因,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了垂蜗?” 一聲冷哼從身側(cè)響起楷扬,我...
    開封第一講書人閱讀 38,926評論 0 274
  • 序言:老撾萬榮一對情侶失蹤解幽,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后烘苹,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體躲株,經(jīng)...
    沈念sama閱讀 45,341評論 1 311
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,563評論 2 333
  • 正文 我和宋清朗相戀三年镣衡,在試婚紗的時候發(fā)現(xiàn)自己被綠了霜定。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,731評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡廊鸥,死狀恐怖望浩,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情惰说,我是刑警寧澤磨德,帶...
    沈念sama閱讀 35,430評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站吆视,受9級特大地震影響典挑,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜揩环,卻給世界環(huán)境...
    茶點故事閱讀 41,036評論 3 326
  • 文/蒙蒙 一搔弄、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧丰滑,春花似錦顾犹、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,676評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至郁妈,卻和暖如春浑玛,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背噩咪。 一陣腳步聲響...
    開封第一講書人閱讀 32,829評論 1 269
  • 我被黑心中介騙來泰國打工顾彰, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人胃碾。 一個月前我還...
    沈念sama閱讀 47,743評論 2 368
  • 正文 我出身青樓涨享,卻偏偏與公主長得像,于是被迫代替她去往敵國和親仆百。 傳聞我的和親對象是個殘疾皇子厕隧,可洞房花燭夜當晚...
    茶點故事閱讀 44,629評論 2 354

推薦閱讀更多精彩內(nèi)容