ConstraintLayout的基本用法及優點
為什麼推薦使用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,無論從開發速度還是頁面的渲染速度都是提升明顯的。
更多Android、Java進階知識微信搜尋公眾號:南京Android部落