爲什麼推薦使用ConstraintLayout
ConstraintLayout(約束佈局)在2016年的Google I/O大會上就推出來了,經歷這兩年的迭代,功能已經非常的成熟了。一次偶然的機會,在項目中嘗試了使用約束佈局,從此被它的功能所深深折服。它能很輕易的將你從使用層層的嵌套去實現複雜的佈局中解放出來。使用ConstraintLayout後基本可以拋棄LinearLayout和RelativeLayout的使用。完全不需要任何嵌套就可以實現複雜的UI,使用起來特別清爽。所以相信我,使用過就會愛上它。
約束佈局的終極奧義!
① 如何才能使用?
因爲ConstraintLayout的是在Support包中提供的,所以只需要在我們主Module的build.gradle中添加如下依賴:
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
然後,我們就可以直接在我們的xml文件中直接應用了:
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" xmlns:tools="http://schemas.android.com/tools" android:background="@color/white" xmlns:app="http://schemas.android.com/apk/res-auto"> <!--具體佈局--> </android.support.constraint.ConstraintLayout>
② 可以用來幹什麼?
- layout_constraintDimensionRatio(控制佈局比例): 我們經常會遇到某些佈局需要展示特殊的比例(16:9、2:1、4:3等等)。在以前我們可能會自定義一個ViewGroup,動態的去計算比例,比較麻煩。而使用ConstraintLayout後,我們可以直接使用這個屬性,以設置某個View的長寬比例爲16:9爲例:
<ImageView android:layout_width="match_parent" android:layout_height="@dimen/dimen_0dp" app:layout_constraintDimensionRatio="16:9"/>
- layout_constraintRight_toRightOf(與RelativeLayout相似的屬性toRightOf等一整套的屬性): 如果你想使用RelativeLayout中的toLeftOf或者toRightOf等屬性,約束佈局同樣提供了一套類似的屬性。比如:按鈕A在屏幕的左上方;按鈕B在按鈕A的右方;按鈕C在按鈕B的下方並且水平居中;按鈕D在按鈕C的下方並且處於屏幕的右側。
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" xmlns:tools="http://schemas.android.com/tools" android:background="@color/white" xmlns:app="http://schemas.android.com/apk/res-auto"> <Button android:id="@+id/this_is_a" android:layout_width="150dp" android:layout_height="50dp" android:textSize="@dimen/dimen_20sp" android:textColor="@color/black" android:text="A" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintTop_toTopOf="parent"/> <Button android:id="@+id/this_is_b" android:layout_width="150dp" android:layout_height="50dp" android:textSize="@dimen/dimen_20sp" android:textColor="@color/black" android:text="B" app:layout_constraintTop_toTopOf="parent" app:layout_constraintLeft_toRightOf="@+id/this_is_a"/> <Button android:id="@+id/this_is_c" android:layout_width="150dp" android:layout_height="50dp" android:textSize="@dimen/dimen_20sp" android:textColor="@color/black" android:text="C" android:layout_marginTop="@dimen/dimen_10dp" app:layout_constraintTop_toBottomOf="@+id/this_is_b" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent"/> <Button android:id="@+id/this_is_d" android:layout_width="150dp" android:layout_height="50dp" android:textSize="@dimen/dimen_20sp" android:textColor="@color/black" android:text="D" android:layout_marginTop="@dimen/dimen_10dp" app:layout_constraintTop_toBottomOf="@+id/this_is_c" app:layout_constraintRight_toRightOf="parent"/> </android.support.constraint.ConstraintLayout>
- layout_constraintHorizontal_chainStyle 對於按鈕A和按鈕B在橫向上,我們通過更改其chainStyle屬性(packed、spread、spread_inside)。
<Button android:id="@+id/this_is_a" android:layout_width="150dp" android:layout_height="50dp" android:textSize="@dimen/dimen_20sp" android:textColor="@color/black" android:text="A" app:layout_constraintHorizontal_chainStyle="packed" app:layout_constraintRight_toLeftOf="@+id/this_is_b" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintTop_toTopOf="parent"/> <Button android:id="@+id/this_is_b" android:layout_width="150dp" android:layout_height="50dp" android:textSize="@dimen/dimen_20sp" android:textColor="@color/black" android:text="B" app:layout_constraintTop_toTopOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintLeft_toRightOf="@+id/this_is_a"/>
- Barrier
我們經常會有這樣的需求,我們某一個控件必須在某一組控件的某一側。如下圖所示button和textView無論位置或者長度怎麼變化,checbox始終在他們的右側。
xml中我們需要使用android.support.constraint.Barrier:
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" xmlns:tools="http://schemas.android.com/tools" android:background="@color/white" xmlns:app="http://schemas.android.com/apk/res-auto"> <Button android:id="@+id/this_is_a" android:layout_width="wrap_content" android:layout_height="50dp" android:textSize="@dimen/dimen_20sp" android:textColor="@color/black" android:text="AAAAAAAAAAAAAAAAAA" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintTop_toTopOf="parent"/> <TextView android:id="@+id/this_is_b" android:layout_width="wrap_content" android:layout_height="50dp" android:textSize="@dimen/dimen_20sp" android:textColor="@color/black" android:text="BBBB" app:layout_constraintTop_toBottomOf="@+id/this_is_a"/> <android.support.constraint.Barrier android:id="@+id/this_is_barrier" android:layout_width="wrap_content" android:layout_height="wrap_content" app:barrierDirection="end" app:constraint_referenced_ids="this_is_a,this_is_b" /> <CheckBox android:id="@+id/this_is_c" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="@dimen/dimen_20sp" android:textColor="@color/black" android:text="CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC" android:layout_marginTop="@dimen/dimen_10dp" app:layout_constraintLeft_toRightOf="@+id/this_is_barrier"/> </android.support.constraint.ConstraintLayout>
- Group 在以前,如果我們需要控制某一組控件的隱藏或者顯示,通常會使用一個ViewGroup包裹一下,但是現在有了Group,完全不需要了,還是上面同樣的例子,我們加一個Group:
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" xmlns:tools="http://schemas.android.com/tools" android:background="@color/white" xmlns:app="http://schemas.android.com/apk/res-auto"> <Button android:id="@+id/this_is_a" android:layout_width="wrap_content" android:layout_height="50dp" android:textSize="@dimen/dimen_20sp" android:textColor="@color/black" android:text="AAAAAAAAAAAAAAAAAA" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintTop_toTopOf="parent"/> <TextView android:id="@+id/this_is_b" android:layout_width="wrap_content" android:layout_height="50dp" android:textSize="@dimen/dimen_20sp" android:textColor="@color/black" android:text="BBBB" app:layout_constraintTop_toBottomOf="@+id/this_is_a"/> <android.support.constraint.Group android:id="@+id/this_is_group" android:visibility="invisible" android:layout_width="wrap_content" android:layout_height="wrap_content" app:constraint_referenced_ids="this_is_a,this_is_b"/> <android.support.constraint.Barrier android:id="@+id/this_is_barrier" android:layout_width="wrap_content" android:layout_height="wrap_content" app:barrierDirection="end" app:constraint_referenced_ids="this_is_a,this_is_b" /> <CheckBox android:id="@+id/this_is_c" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="@dimen/dimen_20sp" android:textColor="@color/black" android:text="CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC" android:layout_marginTop="@dimen/dimen_10dp" app:layout_constraintLeft_toRightOf="@+id/this_is_barrier"/> </android.support.constraint.ConstraintLayout>
通過控制Group的可見性即可控制referenced_ids中申明的控件組的可見性了。注意一點,不要把一個控件申明在不同的Group中,這樣有可能會導致設置可見性失效哦。
- Guideline
利用這個控件,可以輔助我們佈局UI。在實際運行以後,這條線我們是看不到的:
佈局我們可以這麼寫:
<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.support.constraint.Guideline android:id="@+id/guideline" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical" app:layout_constraintGuide_begin="16dp" /> <TextView android:id="@+id/textView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="16dp" app:layout_constraintStart_toStartOf="@+id/guideline" app:layout_constraintTop_toTopOf="parent" tools:text="TextView" /> </android.support.constraint.ConstraintLayout>
有什麼優點
上面介紹了ConstraintLayout的部分功能,強烈推薦你去使用感受一下,在你使用過程中才能真正的體會到爽快。那我們使用約束佈局會有什麼優點呢? 我們使用ConstraintLayout之後,減少了很多的嵌套的層級。這樣View在渲染的時候,減少了很多多餘的measure和layout的開銷。據統計,使用約束佈局替代以前的嵌套結構可以提升40%的速度。如果你嵌套的層次越多,提升的效果越明顯。所以,建議我們現在的開發者強制推行使用ConstraintLayout,無論從開發速度還是頁面的渲染速度都是提升明顯的。