ConstraintLayout的使用教程

該篇文章的主旨是幫助開發者瞭解ConstraintLayout的基本使用方法以及在平常開發項目中的使用場景的說明android

ConstraintLayout官方文檔

ConstraintLayout是一個ViewGroup,容許你靈活的指定子View的位置和大小(具體多靈活在下面的場景中進行說明),官方文檔中說明ConstraintLayout的特性有如下幾種:bash

  • Relative positioning - 相對位置
  • Margins - 邊距
  • Centering positioning - 位置居中
  • Visibility behavior - 可見性行爲
  • Dimension constraints - 尺寸限制
  • Chains - 鏈
  • Virtual Helpers objects - 虛擬幫助對象(Guideline)
  • Optimizer - 優化

以上幾個特性部分有點抽象,官方文檔中也對每個特性都進行了詳細的說明和舉例,有意者能夠單獨去查閱,ConstraintLayout , 在下面的應用場景中也會穿插說明。對於開發者來講,主要了解使用場景和在項目中如何使用,用得多了就對該控件有了比較深刻的瞭解。再看文檔會更容易理解。畢竟文檔是英文的。app

使用說明

在沒有ConstraintLayout以前咱們寫佈局通常使用到的佈局就是相對佈局線性佈局,相對佈局中控件的位置都是基於另外一個控件的位置,這個和ConstraintLayout有一絲類似之處,線性佈局就是直接以瀑布流的形式進行佈局。ConstraintLayout根據字面意思瞭解爲約束佈局,因此,因此在寫佈局文件的時候,須要對每個控件進行約束 ,對每個顯示在約束佈局中的內容進行約束,約束其大小,位置。下面介紹一下約束佈局的相關屬性和使用。ide

ConstraintLayout的基本屬性

決定視圖的大小和位置能夠由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>
複製代碼

很簡單的一個頁面,若是用LinearLayout更快,可是ConstraintLayout自己就是爲了解決複雜佈局而生的,在平常開發中的需求可能會讓你各類嵌套佈局,可是ConstraintLayout基本上都是一個佈局就能夠ok,因此只有你瞭解後才知道使用有多得勁,如今簡單的分析說明下上面的佈局原理。

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,這樣控件就直接居中了。 設計

在給控件添加完約束以後,若是width或者height給的值爲0,則控件的大小將徹底按照約束的大小進行展現,若是設置了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" />
複製代碼

在上面的註冊控件中,增長了layout_constraintBaseline_toBaselineOf屬性,依賴登陸按鈕,這樣他們的繪製基線就在同一y軸上了,從而達到對齊的效果。

Chains

在上面的基線約束中,可能你會發現登陸和註冊的位置很是對稱,這個就是chains約束,對於chains約束只說明兩點,你就會輕鬆使用了。

  • 控件之間要相互依賴。

例如上面的登陸和註冊兩個按鈕,登陸的右邊距約束必須添加到註冊的左邊距上,即:登陸的 end_ToStartOf="btn_sign_up",註冊的 start_toEndOf="btn_login",若是是多個控件同樣,一個控件的結束依賴到另外一個的開始。這是水平chain , 垂直的桶裏

  • 添加chain屬性 待須要增長chain約束的控件都依賴完了以後,就須要給每一個控件增長chain屬性了,即:layout_constraintHorizontal_chainStyle 或者 layout_constraintVertical_chainStyle , 該屬性能夠有多個值,分別對應的效果借鑑官方文檔的,以下:

Dimension constraints - 尺寸約束

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"
        />
複製代碼

這樣就比較輕鬆的實現了高是寬的2倍,在什麼機型上都是。

百分比約束

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"
        />
複製代碼

百分比約束相對很實用,可是比較少用,很相似以前LinearLayout的weight權重。

Visibility behavior

可見性行爲的屬性包括:

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 - Virtual Helpers objects

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" />
複製代碼

中間的虛線,即爲增長的輔助GuideLine控件,該控件須要設置兩個屬性,第一是設置orientation屬性,垂直或者水平,第二是百分比 layout_constraintGuide_percent,添加好輔助視圖以後,其餘控件就能夠依賴於它進行佈局。

以上幾方面就是在平常開發中的基礎使用相關介紹,掌握了這些基本上都能知足開發的需求,下面說下ConstraintLayout的使用場景

使用場景

  • 不帶滾動的複雜佈局

之前咱們在實現佈局的時候常常各類嵌套,如今不帶滾動的佈局,均可以只用一個父佈局就能夠解決,減小了佈局的層級深度

  • 帶滾動的複雜佈局

在NestedScrollView中嵌套一個ConstraintLayout便可。

  • RecyclerView的item佈局

之前item佈局也是各類嵌套佈局,有了ConstraintLayout以後發現真的是省事了不少,代碼看起來也比較舒服

  • 尺寸約束和百分比的巧用

像有一些banner圖的設計尺寸都是固定的,咱們只須要寬度設置全屏,而後設置寬高比,就能適配全部屏幕,等等。。妙用不少,實際開發本身發掘。

總之若是在使用ConstraintLayout看了該內容哪裏不對但願評論補充,或者不對的地方糾正我一下,若是是沒有用過的,但願你趕忙用起來,省時省力

相關文章
相關標籤/搜索