ConstraintLayout 又名約束布局刷晋,出世于谷歌的大懷抱中蓖议,公布在2016年谷歌大會史汗,現(xiàn)如今已經(jīng)不是那個弱小病多的小子了,它被越來越多的人所認識。
在Android studio2.3版本中窍侧,新建布局時已經(jīng)默認的把constraintlayout作為根布局县踢,這其中所代表的含義估計也不用我再次詳說了。所以你還有什么理由不去學(xué)習(xí)伟件?
截止到目前(2017-11-26)硼啤,constraintlayout最新的版本是
implementation 'com.android.support.constraint:constraint-layout:1.1.0-beta3'
這里的beta版本我在用的過程中暫時覺得還OK,如果你覺得beta的版本可能有坑斧账,那你可以使用穩(wěn)定的版本
implementation 'com.android.support.constraint:constraint-layout:1.0.2'
用102版本的時候谴返,似乎是不用加入谷歌的倉庫,代碼應(yīng)該還是在jcenter倉庫中咧织,但是如果使用110版本的話就需要添加谷歌倉庫
repositories {
google()
}
當(dāng)然嗓袱,我下面的例子是使用的110版本,畢竟后面版本的東西多了很多實用的功能习绢,比如 Barrier 這個屬性渠抹,賊雞兒好用,下面慢慢介紹吧毯炮。
整體的圖片是這樣的逼肯,可以在編輯視圖中進行拖拉拽放等操作,想要學(xué)視圖編輯的話桃煎,點雞這里去學(xué)習(xí)吧,別人的大刊,比較詳細为迈,我下面說的是寫代碼的形式,畢竟傳統(tǒng)的手活不能丟叭本(別污啊葫辐,我認真的)
呃,你也看到了伴郁,我本次想舉個栗子耿战,就是中間兒那個雞,在放大點看看
布局真的很簡單焊傅,如果用線性布局或者相對布局剂陡,似乎兒會有嵌套,是似乎兒啊狐胎,有高手也是不嵌套也能搞定的_
在看看我實現(xiàn)這個布局的代碼吧鸭栖,可能對于沒接觸過這個布局的人覺得,怎么代碼辣么多握巢,好吧晕鹊,確實是多,不過都是精,咳咳溅话,華
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<ImageView
android:id="@+id/shopImage"
android:layout_width="0dp"
android:layout_height="100dp"
android:layout_marginTop="10dp"
android:src="@mipmap/test"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="@+id/guideLine2"
app:layout_constraintTop_toTopOf="parent"
/>
<android.support.constraint.Guideline
android:id="@+id/guideLine2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.35"
/>
<TextView
android:id="@+id/shopName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="冬季大棉衣"
app:layout_constraintLeft_toLeftOf="@+id/guideLine2"
app:layout_constraintTop_toTopOf="@+id/shopImage"
app:layout_constraintBottom_toTopOf="@+id/shopAddress"
/>
<TextView
android:id="@+id/shopAddress"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="商品所在地點比較長"
app:layout_constraintLeft_toLeftOf="@+id/guideLine2"
app:layout_constraintTop_toBottomOf="@+id/shopName"
app:layout_constraintBottom_toTopOf="@+id/shopPrice"
/>
<TextView
android:id="@+id/shopPrice"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="價格是10蚊雞"
app:layout_constraintLeft_toLeftOf="@+id/guideLine2"
app:layout_constraintTop_toBottomOf="@+id/shopAddress"
app:layout_constraintBottom_toBottomOf="@+id/shopImage"
/>
<android.support.constraint.Barrier
android:id="@+id/barrier1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:barrierDirection="right"
app:constraint_referenced_ids="shopPrice,shopAddress,shopName"/>
<Button
android:id="@+id/cancelOrder"
android:layout_width="wrap_content"
android:layout_height="40dp"
android:text="取消訂單"
app:layout_constraintLeft_toLeftOf="@+id/barrier1"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="@+id/shopImage"
app:layout_constraintBottom_toTopOf="@+id/gotoPay"
/>
<Button
android:id="@+id/gotoPay"
android:layout_width="wrap_content"
android:layout_height="40dp"
android:text="去付款"
app:layout_constraintLeft_toLeftOf="@+id/barrier1"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/cancelOrder"
app:layout_constraintBottom_toBottomOf="@+id/shopImage"
/>
<android.support.constraint.Group
android:id="@+id/buttonGroup"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:constraint_referenced_ids="gotoPay,cancelOrder"/>
</android.support.constraint.ConstraintLayout>
嗯晓锻,慢慢的來解析吧。先學(xué)習(xí)一下最基本的屬性
- 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_constraintStart_toStartOf
- layout_constraintStart_toEndOf
- layout_constraintEnd_toStartOf
- layout_constraintEnd_toEndOf
- layout_constraintBaseline_toBaselineOf
- 這個應(yīng)該很好理解飞几,相對布局砚哆,該控件在目標控件的xxx(上下左右)
- start_to_start_of跟left_to_left_of有什么區(qū)別?這個跟margin_left和margin_start的用法一樣循狰,還是不知道窟社??(黑人問號)
MarginStart指的是控件距離開頭View部分的間距大小绪钥,MarginLeft則指的是控件距離左邊View部分的間距大小灿里,MarginEnd和MarginRight同理。 - 根局部就是constraintlayout程腹,是Android支持包下的一個新布局匣吊,全類名記得填完
-
baseline_to_baseline_of這個又是什么?
其實baseline就是基線寸潦,比如兩個textView色鸳,要使他們的文字排成一排,那么用baseLine對齊就好了见转。
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<TextView
android:id="@+id/text1"
android:layout_width="100dp"
android:layout_height="100dp"
android:background="@android:color/darker_gray"
android:text="文本1"
android:textSize="20sp"
android:textColor="@android:color/black"
android:gravity="center"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
/>
<TextView
android:layout_width="180dp"
android:layout_height="100dp"
android:background="@android:color/darker_gray"
android:text="文本2和文本1對其"
android:textSize="20sp"
android:textColor="@android:color/black"
app:layout_constraintBaseline_toBaselineOf="@id/text1"
app:layout_constraintLeft_toRightOf="@+id/text1"
app:layout_constraintRight_toRightOf="parent"
/>
</android.support.constraint.ConstraintLayout>
現(xiàn)在在回到剛才的例子中命雀,是不是看得很明白了?打住斩箫,好像還有幾個不認識的吏砂,layout_constraintDimensionRatio又是什么?
有時候我們在設(shè)置圖片的時候乘客,因為圖片太大了狐血,想要按比例去縮放圖片,你是不是去看看這個圖片多大易核,然后拿計算器去算如果寬等于xx匈织,那么高等于yyy?亦或者是在代碼中去計算牡直?別傻了缀匕,現(xiàn)在有了這個屬性就搞定,layout_constraintDimensionRatio默認定義的是寬高比井氢,如1:2就是寬高比例1比2弦追,但是有個前提是,如果已知寬100dp花竞,想要設(shè)置寬高比劲件,那么高必須設(shè)置為0dp掸哑,不然比例設(shè)置沒效果,相反成立零远。
什么苗分?我偏偏要設(shè)置高寬比呢,就不喜歡寬高比牵辣,賊雞兒跟你玩摔癣,別怕,谷歌爸爸不是吃素的纬向,設(shè)置成這樣也行
app:layout_constraintDimensionRatio="h,1:2"
Guideline 又是什么择浊?咳咳,我有句mmp不知當(dāng)講不當(dāng)講逾条。
guideline是constraintlayout的一個工具琢岩,只能用于該布局中,在其他布局中使用無效师脂。這個東西我理解的話担孔,相當(dāng)于margin,也可以叫做事輔助線吃警。圖中的虛線就是guideline
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="距離左邊100dp1"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
android:layout_marginTop="20dp"
android:layout_marginLeft="100dp"
/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="距離左邊100dp2"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
android:layout_marginTop="80dp"
android:layout_marginLeft="100dp"
/>
<android.support.constraint.Guideline
android:id="@+id/guide1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_begin="100dp"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="距離左邊100dp3"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="@+id/guide1"
android:layout_marginTop="150dp"
/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="距離左邊100dp4"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="@+id/guide1"
android:layout_marginTop="210dp"
/>
</android.support.constraint.ConstraintLayout>
Barrier這個呢糕篇,在1.0.x版本中這個屬性是不存在的,只有在1.1.x版本后存在酌心。但是這個屬性真的賊雞兒好玩
具體的應(yīng)用場景我就不說了拌消,先上圖讓你明明白白的。
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="這個是按鈕1"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginLeft="20dp"
android:layout_marginTop="20dp"
/>
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="你是不是沒看過那么長的按鈕呢"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@+id/button1"
android:layout_marginLeft="20dp"
android:layout_marginTop="20dp"
/>
<android.support.constraint.Barrier
android:id="@+id/barrier1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:barrierDirection="right"
app:constraint_referenced_ids="button2,button1"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="我在他們的后面"
app:layout_constraintLeft_toLeftOf="@+id/barrier1"
tools:layout_editor_absoluteY="40dp"/>
<Button
android:id="@+id/button3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="你是不是沒看過那么長的按鈕呢"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginLeft="20dp"
android:layout_marginTop="170dp"
/>
<Button
android:id="@+id/button4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="這個按鈕4"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@+id/button3"
android:layout_marginLeft="20dp"
android:layout_marginTop="20dp"
/>
<android.support.constraint.Barrier
android:id="@+id/barrier2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:barrierDirection="right"
app:constraint_referenced_ids="button3,button4"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="我還在右邊"
app:layout_constraintLeft_toLeftOf="@+id/barrier2"
tools:layout_editor_absoluteY="208dp"/>
</android.support.constraint.ConstraintLayout>
constraint.Group 這個比較簡單拼坎,可以理解為一個控件把一些其他控件包起來,一起做一些羞羞的事情完疫,比如咳咳咳,想啥呢债蓝,我是說把它們藏起來壳鹤。
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="這個是按鈕1"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginLeft="20dp"
android:layout_marginTop="20dp"
/>
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="這個是按鈕2"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@+id/button1"
android:layout_marginLeft="20dp"
android:layout_marginTop="20dp"
/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="這個是按鈕3"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@+id/button2"
android:layout_marginLeft="20dp"
android:layout_marginTop="20dp"
/>
<android.support.constraint.Group
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="invisible"
app:constraint_referenced_ids="button1,button2"/>
</android.support.constraint.ConstraintLayout>
很簡單是不是,相當(dāng)于一同處理了饰迹。以上的一些屬性都是在相對布局中相似的芳誓,你有沒有疑問,線性布局LinearLayout的權(quán)重Weight屬性啊鸭,怎么才能在約束布局中體現(xiàn)呢锹淌,別急,慢慢玩雞兒赠制。
Chains隆重出場赂摆,好像沒人歡迎,趕快鼓掌,呃烟号,沒人認識0硖贰!
不介紹什么是鏈條了汪拥,其實就是你依賴我我依賴你达传,你儂我儂的一種狀態(tài),互相依賴迫筑,使得他們存在一定的關(guān)系宪赶。默認的鏈條樣式是Spread chain.
下面我一一舉例子說明,其實就實現(xiàn)上面的幾種可能脯燃。
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<android.support.constraint.Guideline
android:id="@+id/guide1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_begin="10dp"/>
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="我做飯"
app:layout_constraintTop_toTopOf="@+id/guide1"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@+id/button2"
/>
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="我洗菜"
app:layout_constraintTop_toTopOf="@+id/guide1"
app:layout_constraintLeft_toRightOf="@+id/button1"
app:layout_constraintRight_toLeftOf="@+id/button3"
/>
<Button
android:id="@+id/button3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="那我做菜"
app:layout_constraintTop_toTopOf="@+id/guide1"
app:layout_constraintLeft_toRightOf="@+id/button2"
app:layout_constraintRight_toRightOf="parent"
/>
</android.support.constraint.ConstraintLayout>
在 button1 中加入layout_constraintHorizontal_chainStyle屬性就能變成不一樣的風(fēng)格
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="我做飯"
app:layout_constraintHorizontal_chainStyle="spread_inside"
app:layout_constraintTop_toTopOf="@+id/guide1"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@+id/button2"
/>
再變Packed chain
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="我做飯"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintTop_toTopOf="@+id/guide1"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@+id/button2"
/>
再變Spread weight chain
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<android.support.constraint.Guideline
android:id="@+id/guide1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_begin="10dp"/>
<Button
android:id="@+id/button1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="我做飯"
app:layout_constraintHorizontal_chainStyle="spread"
app:layout_constraintHorizontal_weight="3"
app:layout_constraintTop_toTopOf="@+id/guide1"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@+id/button2"
/>
<Button
android:id="@+id/button2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="我洗菜"
app:layout_constraintTop_toTopOf="@+id/guide1"
app:layout_constraintHorizontal_weight="2"
app:layout_constraintLeft_toRightOf="@+id/button1"
app:layout_constraintRight_toLeftOf="@+id/button3"
/>
<Button
android:id="@+id/button3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="那我做菜"
app:layout_constraintTop_toTopOf="@+id/guide1"
app:layout_constraintLeft_toRightOf="@+id/button2"
app:layout_constraintRight_toRightOf="parent"
/>
</android.support.constraint.ConstraintLayout>
再變packed chain with bias搂妻,什么是bias,等會解析
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="我做飯"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintHorizontal_bias="0.2"
app:layout_constraintTop_toTopOf="@+id/guide1"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@+id/button2"
/>
對曲伊,你也看到啦叽讳,實際上是加了這個layout_constraintHorizontal_bias屬性,它是啥坟募?它是牛x的百分比屬性岛蚤,也叫做偏移,有橫向的偏移懈糯,也有豎直方向的偏移涤妒。
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="居中貼上顯示"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
/>
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="距離左邊是屏幕的百分之30"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintHorizontal_bias="0.3"
/>
<Button
android:id="@+id/button3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="貼近右邊"
app:layout_constraintTop_toBottomOf="@+id/button2"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintHorizontal_bias="1"
/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="貼底部顯示"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintVertical_bias="1"
/>
</android.support.constraint.ConstraintLayout>
官方文檔中還有 ConstraintSet 和 Placeholder 這個東西,不過還沒接觸到赚哗,就先不介紹了她紫。看起來Placeholder這玩兒似乎還挺好玩的
呃屿储,最后說兩句吧贿讹,自從學(xué)了這布局,我就拋棄了其他布局了够掠,官方推薦的民褂,沒毛病,有人測試過性能方面的疯潭,不過我沒測試赊堪,這是別人家的測試性能對比,我覺得沒啥的竖哩,只要好用哭廉,和以前的差不多也行