該篇文章的主旨是幫助開發者瞭解ConstraintLayout的基本使用方法以及在平常開發項目中的使用場景的說明android
ConstraintLayout是一個ViewGroup,容許你靈活的指定子View的位置和大小(具體多靈活在下面的場景中進行說明),官方文檔中說明ConstraintLayout的特性有如下幾種:bash
以上幾個特性部分有點抽象,官方文檔中也對每個特性都進行了詳細的說明和舉例,有意者能夠單獨去查閱,ConstraintLayout , 在下面的應用場景中也會穿插說明。對於開發者來講,主要了解使用場景和在項目中如何使用,用得多了就對該控件有了比較深刻的瞭解。再看文檔會更容易理解。畢竟文檔是英文的。app
在沒有ConstraintLayout以前咱們寫佈局通常使用到的佈局就是相對佈局和線性佈局,相對佈局中控件的位置都是基於另外一個控件的位置,這個和ConstraintLayout有一絲類似之處,線性佈局就是直接以瀑布流的形式進行佈局。ConstraintLayout根據字面意思瞭解爲約束佈局,因此,因此在寫佈局文件的時候,須要對每個控件進行約束 ,對每個顯示在約束佈局中的內容進行約束,約束其大小,位置。下面介紹一下約束佈局的相關屬性和使用。ide
決定視圖的大小和位置能夠由View四個邊來肯定,left top right bottom, 因此約束佈局能夠經過對四個邊的約束來達到實際佈局效果,相關四個邊的屬性有,如:佈局
app:layout_constraintLeft_toLeftOf
app:layout_constraintLeft_toRightOf
app:layout_constraintRight_toLeftOf
app:layout_constraintRight_toRightOf
app:layout_constraintTop_toTopOf
app:layout_constraintTop_toBottomOf
app:layout_constraintBottom_toTopOf
app:layout_constraintBottom_toBottomOf
app:layout_constraintStart_toEndOf
app:layout_constraintStart_toStartOf
app:layout_constraintEnd_toStartOf
app:layout_constraintEnd_toEndOf
複製代碼
應該根據這些屬性的名稱就能瞭解它們的做用,下面舉例說明:好比實現一個登錄界面,兩個文本框和一個按鈕。優化
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.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">
<EditText
android:id="@+id/edt_username"
android:layout_width="0dp"
android:layout_height="50dp"
android:layout_marginStart="25dp"
android:layout_marginTop="200dp"
android:layout_marginEnd="25dp"
android:hint="請輸入用戶名"
android:inputType="text"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<EditText
android:id="@+id/edt_password"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="25dp"
android:hint="請輸入密碼"
android:inputType="textPassword"
app:layout_constraintEnd_toEndOf="@id/edt_username"
app:layout_constraintStart_toStartOf="@id/edt_username"
app:layout_constraintTop_toBottomOf="@id/edt_username" />
<Button
android:id="@+id/btn_login"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
android:text="登 錄"
app:layout_constraintEnd_toEndOf="@id/edt_password"
app:layout_constraintStart_toStartOf="@id/edt_password"
app:layout_constraintTop_toBottomOf="@id/edt_password" />
</androidx.constraintlayout.widget.ConstraintLayout>
複製代碼
1.肯定用戶名EditText的位置和大小,從四個邊來約束,首先約束top,使用top_toTopOf="parent"將用戶名EditText的頂部和父佈局的頂部關聯起來,而後經過marginTop來增長邊距,若是不設置top_toTopOf屬性,marginTop屬性是不起做用的,任何沒有增長約束的邊設置margin屬性都是不起做用的,上面的代碼中咱們將EditText的width設置爲0dp,而後給左右兩邊分別增長了約束,約束到父佈局的start和end,經過以上三個屬性,就肯定了該EditText的位置和大小。ui
2.肯定了用戶名EditText的位置以後,進行添加密碼EditText,和上一個EditText相似,增長左右上三邊的約束,不一樣的是top_toTopOf屬性的值改成了edt_username,不在把約束添加到parent,而是添加到用戶名的EditText,這樣密碼EditText就顯示到用戶名的下面了。登陸同理加密
只須要記住,ConstraintLayout中的全部空間添加上 左上右下 四個邊的約束,就能肯定空間的位置(對應了開始說的 Relative positioning 和 Margins 兩個特性) ,記住這個就掌握使用的一大半了spa
想讓控件居中也很簡單,好比說上面的登陸按鈕,不想要那麼大,能夠將控件的width屬性改爲wrap_content,這樣控件就直接居中了。 設計
該約束是針對文本相關控件添加的,好比要再添加一個註冊按鈕在登陸的右側
<Button
android:id="@+id/btn_login"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
android:text="登 錄"
app:layout_constraintEnd_toStartOf="@id/btn_sign_up"
app:layout_constraintHorizontal_chainStyle="spread"
app:layout_constraintStart_toStartOf="@id/edt_password"
app:layout_constraintTop_toBottomOf="@id/edt_password" />
<Button
android:id="@+id/btn_sign_up"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="註冊"
app:layout_constraintBaseline_toBaselineOf="@id/btn_login"
app:layout_constraintHorizontal_chainStyle="spread"
app:layout_constraintStart_toEndOf="@id/btn_login"
app:layout_constraintEnd_toEndOf="@id/edt_password"
app:layout_constraintTop_toBottomOf="@id/edt_password" />
複製代碼
在上面的基線約束中,可能你會發現登陸和註冊的位置很是對稱,這個就是chains約束,對於chains約束只說明兩點,你就會輕鬆使用了。
例如上面的登陸和註冊兩個按鈕,登陸的右邊距約束必須添加到註冊的左邊距上,即:登陸的 end_ToStartOf="btn_sign_up",註冊的 start_toEndOf="btn_login",若是是多個控件同樣,一個控件的結束依賴到另外一個的開始。這是水平chain , 垂直的桶裏
layout_constraintDimensionRatio
尺寸約束的使用很少,可是這個屬性很重要,在不少的場景中可使用該約束,先對屬性進行說明,應用場景後面再說。瞭解了做用,天然就能在實際開發中找到場景。好比說咱們要實現一個ImageView的寬是高的2倍,可能有人想,我把寬固定了那高除以2不就出來了嘛,固然能夠,可是有些場景,好比說寬是屏幕的寬度,match_parent呢,用尺寸約束就能夠很輕鬆的達到效果。
<ImageView
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintDimensionRatio="2:1"
android:background="@color/colorAccent"
/>
複製代碼
layout_constraintHeight_percent
layout_constraintWidth_percent
分別對寬高進行百分比約束。
<ImageView
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintHeight_percent="0.2"
app:layout_constraintWidth_percent="0.5"
android:background="@color/colorAccent"
/>
複製代碼
可見性行爲的屬性包括:
layout_goneMarginStart
layout_goneMarginEnd
layout_goneMarginLeft
layout_goneMarginTop
layout_goneMarginRight
layout_goneMarginBottom
複製代碼
好比說上面的登陸頁面,若是程序中設置了用戶名EditText設置了setVisible(false),那麼密碼EditText就會直接到頂部了,甚至形成佈局錯亂,爲何?應爲密碼EditText的左右約束添加到了用戶名的EditText上,若是想讓用戶名EditText隱藏的時候密碼EditText和top右邊距,就能夠給密碼EditText加上goneMarginTop屬性,爲了防止由於控件隱藏形成佈局錯亂,在已知一些控件會隱藏的前提下,其餘的控件不要左右邊依賴可能會隱藏的視圖,防止佈局錯亂 好比上面的爲了防止用戶名EditText隱藏形成密碼EditText顯示不了的問題,能夠給密碼EditText的左右依賴添加到父佈局便可。
guideline也是一個控件,可是這個控件是隻在約束佈局中才能起做用的輔助控件 ,是幫助輔助佈局的,好比說,咱們添加一個GuideLine,將屏幕平分爲兩半,一個視圖在左,一個在右。拿上面的登陸註冊兩個按鈕來講,上面的實現方式是增長了chain約束,也能夠用GuideLine來實現。代碼以下:
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.5" />
<Button
android:id="@+id/btn_login"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
android:text="登 錄"
app:layout_constraintEnd_toStartOf="@id/guideline"
app:layout_constraintStart_toStartOf="@id/edt_password"
app:layout_constraintTop_toBottomOf="@id/edt_password" />
<Button
android:id="@+id/btn_sign_up"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="註冊"
app:layout_constraintBaseline_toBaselineOf="@id/btn_login"
app:layout_constraintEnd_toEndOf="@id/edt_password"
app:layout_constraintStart_toEndOf="@id/guideline" />
複製代碼
以上幾方面就是在平常開發中的基礎使用相關介紹,掌握了這些基本上都能知足開發的需求,下面說下ConstraintLayout的使用場景
之前咱們在實現佈局的時候常常各類嵌套,如今不帶滾動的佈局,均可以只用一個父佈局就能夠解決,減小了佈局的層級深度
在NestedScrollView中嵌套一個ConstraintLayout便可。
之前item佈局也是各類嵌套佈局,有了ConstraintLayout以後發現真的是省事了不少,代碼看起來也比較舒服
像有一些banner圖的設計尺寸都是固定的,咱們只須要寬度設置全屏,而後設置寬高比,就能適配全部屏幕,等等。。妙用不少,實際開發本身發掘。
總之若是在使用ConstraintLayout看了該內容哪裏不對但願評論補充,或者不對的地方糾正我一下,若是是沒有用過的,但願你趕忙用起來,省時省力