ConstraintLayout的 使用大全

2022-01-04 徐公

作者:小立子
來源:https://juejin.cn/post/6844903764462141447

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

ConstraintLayout官方文檔

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

Relative positioning - 相對位置

Margins - 邊距

Centering positioning - 位置居中

Visibility behavior - 可見性行為

Dimension constraints - 尺寸限制

Chains - 鏈

Virtual Helpers objects - 虛擬幫助對象(Guideline)

Optimizer - 優化

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

使用說明

在沒有ConstraintLayout之前我們寫布局一般使用到的布局就是 相對布局 和 線性布局
,相對布局中控制項的位置都是基於另一個控制項的位置,這個和ConstraintLayout有一絲相似之處,線性布局就是直接以瀑布流的形式進行布局。
ConstraintLayout 根據字面意思了解為約束布局,所以,所以在寫布局文件的時候, 需要對每一個控制項進行約束
,對每一個顯示在約束布局中的內容進行約束,約束其大小,位置。下面介紹一下約束布局的相關屬性和使用。

ConstraintLayout的基本屬性

決定視圖的大小和位置可以由View四個邊來確定, left top right bottom ,
所以約束布局可以通過對四個邊的約束來達到實際布局效果,相關四個邊的屬性有,如:

1app:layout_constraintLeft_toLeftOf
2app:layout_constraintLeft_toRightOf
3app:layout_constraintRight_toLeftOf
4app:layout_constraintRight_toRightOf
5app:layout_constraintTop_toTopOf
6app:layout_constraintTop_toBottomOf
7app:layout_constraintBottom_toTopOf
8app:layout_constraintBottom_toBottomOf
9app:layout_constraintStart_toEndOf
10app:layout_constraintStart_toStartOf
11app:layout_constraintEnd_toStartOf
12app:layout_constraintEnd_toEndOf

應該根據這些屬性的名稱就能了解它們的作用,下面舉例說明:比如實現一個登陸界面,兩個文本框和一個按鈕。

1<?xml version="1.0" encoding="utf-8"?>
2<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
3    xmlns:app="http://schemas.android.com/apk/res-auto"
4    xmlns:tools="http://schemas.android.com/tools"
5    android:layout_width="match_parent"
6    android:layout_height="match_parent">
7
8    <EditText
9        android:id="@+id/edt_username"
10        android:layout_width="0dp"
11        android:layout_height="50dp"
12        android:layout_marginStart="25dp"
13        android:layout_marginTop="200dp"
14        android:layout_marginEnd="25dp"
15        android:hint="請輸入用戶名"
16        android:inputType="text"
17        app:layout_constraintEnd_toEndOf="parent"
18        app:layout_constraintStart_toStartOf="parent"
19        app:layout_constraintTop_toTopOf="parent" />
20
21    <EditText
22        android:id="@+id/edt_password"
23        android:layout_width="0dp"
24        android:layout_height="wrap_content"
25        android:layout_marginTop="25dp"
26        android:hint="請輸入密碼"
27        android:inputType="textPassword"
28        app:layout_constraintEnd_toEndOf="@id/edt_username"
29        app:layout_constraintStart_toStartOf="@id/edt_username"
30        app:layout_constraintTop_toBottomOf="@id/edt_username" />
31
32    <Button
33        android:id="@+id/btn_login"
34        android:layout_width="0dp"
35        android:layout_height="wrap_content"
36        android:layout_marginTop="30dp"
37        android:text="登 錄"
38        app:layout_constraintEnd_toEndOf="@id/edt_password"
39        app:layout_constraintStart_toStartOf="@id/edt_password"
40        app:layout_constraintTop_toBottomOf="@id/edt_password" />
41</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的位置和大小。

2.確定了用戶名EditText的位置之後,進行添加密碼EditText,和上一個EditText類似,增加左右上三邊的約束,不同的是top_toTopOf屬性的值改為了edt_username,不在把約束添加到parent,而是添加到用戶名的EditText,這樣密碼EditText就顯示到用戶名的下面了。登錄同理

只需要記住,ConstraintLayout中的所有空間添加上 左上右下 四個邊的約束,就能確定空間的位置(對應了開始說的 Relative positioning 和 Margins 兩個特性) ,記住這個就掌握使用的一大半了

控制項居中

想讓控制項居中也很簡單,比如說上面的登錄按鈕,不想要那麼大,可以將控制項的width屬性改成wrap_content,這樣控制項就直接居中了。


在給控制項添加完約束之後,如果width或者height給的值為0,則控制項的大小將完全按照約束的大小進行展示,如果設置了wrap_content,則控制項會居中顯示

基線對齊約束

該約束是針對文本相關控制項添加的,比如要再添加一個註冊按鈕在登錄的右側

1    <Button
2        android:id="@+id/btn_login"
3        android:layout_width="wrap_content"
4        android:layout_height="wrap_content"
5        android:layout_marginTop="30dp"
6        android:text="登 錄"
7        app:layout_constraintEnd_toStartOf="@id/btn_sign_up"
8        app:layout_constraintHorizontal_chainStyle="spread"
9        app:layout_constraintStart_toStartOf="@id/edt_password"
10        app:layout_constraintTop_toBottomOf="@id/edt_password" />
11
12    <Button
13        android:id="@+id/btn_sign_up"
14        android:layout_width="wrap_content"
15        android:layout_height="wrap_content"
16        android:text="註冊"
17        app:layout_constraintBaseline_toBaselineOf="@id/btn_login"
18        app:layout_constraintHorizontal_chainStyle="spread"
19        app:layout_constraintStart_toEndOf="@id/btn_login"
20        app:layout_constraintEnd_toEndOf="@id/edt_password"
21        app:layout_constraintTop_toBottomOf="@id/edt_password" />


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

Chains

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

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

Dimension constraints - 尺寸約束

layout_constraintDimensionRatio

尺寸約束的使用不多,但是這個屬性很重要,在很多的場景中可以使用該約束,先對屬性進行說明,應用場景後面再說。了解了作用,自然就能在實際開發中找到場景。比如說我們要實現一個ImageView的寬是高的2倍,可能有人想,我把寬固定了那高除以2不就出來了嘛,當然可以,但是有些場景,比如說寬是屏幕的寬度,match_parent呢,用尺寸約束就可以很輕鬆的達到效果。

1  <ImageView
2        android:layout_width="0dp"
3        android:layout_height="0dp" 
4        app:layout_constraintStart_toStartOf="parent"
5        app:layout_constraintEnd_toEndOf="parent"
6        app:layout_constraintTop_toTopOf="parent"
7        app:layout_constraintDimensionRatio="2:1"
8        android:background="@color/colorAccent"
9        />

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

百分比約束

layout_constraintHeight_percent

layout_constraintWidth_percent

分別對寬高進行百分比約束。

1 <ImageView
2        android:layout_width="0dp"
3        android:layout_height="0dp"
4        app:layout_constraintStart_toStartOf="parent"
5        app:layout_constraintEnd_toEndOf="parent"
6        app:layout_constraintTop_toTopOf="parent"
7        app:layout_constraintHeight_percent="0.2"
8        app:layout_constraintWidth_percent="0.5"
9        android:background="@color/colorAccent"
10        />

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

Visibility behavior

可見性行為的屬性包括:

1layout_goneMarginStart
2layout_goneMarginEnd
3layout_goneMarginLeft
4layout_goneMarginTop
5layout_goneMarginRight
6layout_goneMarginBottom

比如說上面的登錄頁面,如果程序中設置了用戶名EditText設置了setVisible(false),那麼密碼EditText就會直接到頂部了,甚至造成布局錯亂,為什麼?應為密碼EditText的左右約束添加到了用戶名的EditText上,如果想讓用戶名EditText隱藏的時候密碼EditText和top右邊距,就可以給密碼EditText加上goneMarginTop屬性,
為了防止因為控制項隱藏造成布局錯亂,在已知一些控制項會隱藏的前提下,其他的控制項不要左右邊依賴可能會隱藏的視圖,防止布局錯亂
比如上面的為了防止用戶名EditText隱藏造成密碼EditText顯示不了的問題,可以給密碼EditText的左右依賴添加到父布局即可。

Guideline - Virtual Helpers objects

guideline也是一個控制項,但是這個控制項是只在約束布局中才能起作用的 輔助控制項
,是幫助輔助布局的,比如說,我們添加一個GuideLine,將屏幕平分為兩半,一個視圖在左,一個在右。拿上面的登錄註冊兩個按鈕來說,上面的實現方式是增加了chain約束,也可以用GuideLine來實現。代碼如下:

1    <androidx.constraintlayout.widget.Guideline
2        android:id="@+id/guideline"
3        android:layout_width="wrap_content"
4        android:layout_height="wrap_content"
5        android:orientation="vertical"
6        app:layout_constraintGuide_percent="0.5" />
7
8    <Button
9        android:id="@+id/btn_login"
10        android:layout_width="wrap_content"
11        android:layout_height="wrap_content"
12        android:layout_marginTop="30dp"
13        android:text="登 錄"
14        app:layout_constraintEnd_toStartOf="@id/guideline"
15        app:layout_constraintStart_toStartOf="@id/edt_password"
16        app:layout_constraintTop_toBottomOf="@id/edt_password" />
17
18    <Button
19        android:id="@+id/btn_sign_up"
20        android:layout_width="wrap_content"
21        android:layout_height="wrap_content"
22        android:text="註冊"
23        app:layout_constraintBaseline_toBaselineOf="@id/btn_login"
24        app:layout_constraintEnd_toEndOf="@id/edt_password"
25        app:layout_constraintStart_toEndOf="@id/guideline" />

中間的虛線,即為增加的輔助GuideLine控制項,該控制項需要設置兩個屬性,第一是設置orientation屬性,垂直或者水平,第二是百分比
layout_constraintGuide_percent,添加好輔助視圖之後,其他控制項就可以依賴於它進行布局。

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

使用場景

以前我們在實現布局的時候經常各種嵌套,現在不帶滾動的布局,都可以只用一個父布局就可以解決,減少了布局的層級深度

在NestedScrollView中嵌套一個ConstraintLayout即可。

以前item布局也是各種嵌套布局,有了ConstraintLayout之後發現真的是省事了很多,代碼看起來也比較舒服

像有一些banner圖的設計尺寸都是固定的,我們只需要寬度設置全屏,然後設置寬高比,就能適配所有屏幕,等等。。妙用很多,實際開發自己發掘。

總之如果在使用ConstraintLayout看了該內容哪裡不對希望評論補充,或者不對的地方糾正我一下,如果是沒有用過的,希望你趕緊用起來,省時省力

如果你覺得對你有所幫助,可以關注我的微信公眾號 程式設計師徐公

Android 啟動優化(一) - 有向無環圖

Android 啟動優化(五)-  AnchorTask 1.0.0 版本正式發布了

什麼?Android webView 的字體突然變小了

相關焦點

  • Android ConstraintLayout使用指南
    ConstraintLayout最低兼容Android 2.3;目前Android Studio 2.3默認使用ConstraintLayout作為布局文件的根布局;想要使用ConstraintLayout,需在項目的build.gradle添加com.android.support.constraint:constraint-layout:XXX版本號依賴
  • ConstraintLayout 介紹
    ConstraintLayout類已經被androidx.constraintlayout.widget.ConstraintLayout所取代。我們建議在所有新項目中使用AndroidX庫。您還應該考慮將現有項目遷移到AndroidX。
  • 強大的 ConstraintLayout
    ,所以這篇文章基本上算是重寫了一遍,有任何不足請大家提出使用方式首先這個布局是要添加 依賴的,一般新建項目會默認添加這個依賴如果沒有也可以手動添加,截止完稿最新版本就是 1.0.2 版本,添加完依賴就能夠使用了compile 'com.android.support.constraint:constraint-layout:1.0.2
  • Android ConstraintLayout約束布局可視化工具使用~
    ,一般新建項目會默認添加這個依賴如果沒有也可以手動添加,截止完稿最新版本就是 1.0.2 版本,添加完依賴就能夠使用了compile 'com.android.support.constraint:constraint-layout:1.0.2'
  • 拒絕拖拽 使用ConstraintLayout優化你的布局吧
    看到這樣的布局,大家條件反射應該就是使用RelativeLayout來做,當然了,本案例我們使用ConstraintLayout來寫::layout_constraintRight_toLeftOflayout_constraintRight_toRightOflayout_constraintTop_toTopOflayout_constraintTop_toBottomOflayout_constraintBottom_toTopOflayout_constraintBottom_toBottomOf
  • Android MotionLayout動畫:續寫ConstraintLayout新篇章
    AndroidX:implementation 'androidx.constraintlayout:constraintlayout:2.0.0-beta8'支持庫:implementation 'com.android.support.constraint
  • 帶你了解 Android 約束布局 ConstraintLayout
    所以極力推薦使用ConstraintLayout來編寫布局。本文主要介紹一下如何使用代碼來編寫ConstraintLayout布局。好了,開始我們的徵程。ConstraintLayout簡介ConstraintLayout,可以翻譯為約束布局,在2016年Google I/O 大會上發布。我們知道,當布局嵌套過多時會出現一些性能問題。
  • MotionLayout系列之配合布局CoordinatorLayout, DrawerLayout, ViewPager使用
    在 Coordinatorlayout 中使用 MotionLayout:( MotionLayout 可以實現類似 CoodinatorLayout 的功能,我們將在以後的文章中提供示例)可以通過 MotionLayout 指定一部分 View 的動畫,將更多有趣的動畫加到已經存在的布局中。
  • 我用ConstraintLayout寫了個登錄頁面,原來是那麼的好用
    app:layout_constraintBottom_toBottomOf="@+id/view1"與之不同的是RelativeLayout,ConstraintLayout提供bias用於相對於手柄以0%和100%水平和垂直偏移定位視圖的值(用圓圈標記)。這些百分比(和分數)提供了跨不同屏幕密度和大小的視圖的無縫定位。
  • MotionLayout 的高級玩法我學會了
    MotionLayout 的思路非常簡單,使用 ConstraintLayout 的寫法,定義動畫開始的一幀和動畫結束的一幀(當然我們也可以加入更多幀,在動畫的過程中),在事件觸發以後,會自動幫我們處理好動畫。不過,本文的重點可不是學習 MotionLayout,而是教大家如何使用 Carousel,可以看一下我寫的效果:
  • 輕鬆掌握RelativeLayout相對布局
    但在實際開發中使用LinearLayout遠遠不夠,我們本期一起來學習RelativeLayout。  二、示例  接下來通過一個簡單的示例程序來學習RelativeLayout的使用用法。Genymotion,跨入火箭時代  Android零基礎入門第15節:掌握Android Studio項目結構,揚帆起航  Android零基礎入門第16節:Android用戶界面開發概述  Android零基礎入門第17節:TextView屬性和方法大全  Android零基礎入門第18節:EditText的屬性和使用方法
  • 如何在Xamarin.Android中使用約束布局
    layout_constraintLeft_toLeftOf-將所需視圖的左側對齊到目標視圖的左側。layout_constraintLeft_toRightOf-將所需視圖的左側對齊到目標視圖的右側。
  • IC Layout 腳本分享
    hlist使用方法:需要把cds.lib 拷貝到與腳本相同的目錄layout_get_hlist.sh your.cdl腳本#2:名字:layout_ic61_strmout.sh語言:shell功能:用腳本導出GDS內容:#!
  • 決策科學 | 利用column-and-constraint算法解決二階段魯棒優化問題
    本文發表於Elsevier旗下期刊Operations Research Letters,文章中作者主要研究如何運用column-and-constraint算法解決二階段的魯棒優化問題。 相比Benders式割平面法,column-and-constraint算法是一種採用統一解法處理最優性和可行性問題的一般程序。
  • layout拼圖軟體
    layout拼圖軟體 攝影錄像 大小: 15.5 MB
  • AutoLayout 實現固定寬度動態高度的 ScrollView
    大多數的 app 需要有響應式布局,所以使用 Autolayout 可謂明智之選。第一次學習 scrollviews 時,你或許會覺得碉堡了。但它們奇怪的規則也會令人有點沮喪。準備你對 Xcode 和 interface builder 都足夠熟悉。