1. 介紹
約束布局ConstraintLayout 是一個(gè)ViewGroup,可以在Api9以上的Android系統(tǒng)使用它,它的出現(xiàn)主要是為了解決布局嵌套過多的問題,以靈活的方式定位和調(diào)整小部件。從 Android Studio 2.3 起,官方的模板默認(rèn)使用 ConstraintLayout。
官方文檔:ConstraintLayout
2. 基本屬性及其使用
要在 ConstraintLayout 中定義某個(gè)視圖的位置,必須為該視圖添加至少一個(gè)水平約束條件和一個(gè)垂直約束條件。每個(gè)約束條件均表示與其他視圖、父布局或隱形引導(dǎo)線之間連接或?qū)R方式。每個(gè)約束條件均定義了視圖在豎軸或者橫軸上的位置;因此每個(gè)視圖在每個(gè)軸上都必須至少有一個(gè)約束條件,但通常情況下會需要更多約束條件。
2.1 相對定位
2.1.1 屬性
1. layout_constraintLeft_toLeftOf
當(dāng)前View的右側(cè)和另一個(gè)View的右側(cè)位置對齊
與RelativeLayout的alignLeft屬性相似
2. layout_constraintLeft_toRightOf
當(dāng)前view的左側(cè)會在另一個(gè)View的右側(cè)位置
與RelativeLayout的toRightOf屬性相似
3. layout_constraintRight_toLeftOf
當(dāng)前view的右側(cè)會在另一個(gè)View的左側(cè)位置
與RelativeLayout的toLeftOf屬性相似
4. layout_constraintRight_toRightOf
當(dāng)前View的右側(cè)和另一個(gè)View的右側(cè)位置對其
與RelativeLayout的alignRight屬性相似
5. layout_constraintTop_toTopOf
頭部對齊,與alignTop相似
6. layout_constraintTop_toBottomOf
當(dāng)前View在另一個(gè)View的下側(cè) 與below相似
7. layout_constraintBottom_toTopOf
當(dāng)前View在另一個(gè)View的上方 與above相似
8. layout_constraintBottom_toBottomOf
底部對齊,與alignBottom屬性相似
9. layout_constraintBaseline_toBaselineOf
文字底部對齊,與alignBaseLine屬性相似
10. layout_constraintStart_toEndOf
同left_toRightOf
11. layout_constraintStart_toStartOf
同left_toLeftOf
12. layout_constraintEnd_toStartOf
同right_toLeftOf
13. layout_constraintEnd_toEndOf
同right_toRightOf
先來看一個(gè)簡單的例子:(如果我們想實(shí)現(xiàn)下面這個(gè)布局
代碼如下:
<?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"
tools:context=".MainActivity">
<TextView
android:id="@+id/textView1"
android:layout_width="100dp"
android:layout_height="60dp"
android:background="#D6E1AA"
android:gravity="center"
android:text="textview1"
android:textColor="@color/black"
android:textSize="25sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="HardcodedText" />
<TextView
android:id="@+id/textView2"
android:layout_width="138dp"
android:layout_height="111dp"
android:background="#E8C99B"
android:gravity="center"
android:text="textview2"
android:textColor="@color/black"
android:textSize="25sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="@+id/textView1"
app:layout_constraintEnd_toStartOf="@+id/textView1"
tools:ignore="HardcodedText" />
</androidx.constraintlayout.widget.ConstraintLayout>
textview2里最重要的兩行代碼:
app:layout_constraintBottom_toBottomOf="@+id/textView1"
app:layout_constraintEnd_toStartOf="@+id/textView1"
我們讓textview2的底部和textview1的底部對齊,讓textview2的右邊和textview1的左邊對齊,就確定了textview2的位置。
有一個(gè)比較好玩的屬性:layout_constraintBaseline_toBaselineOf
Baseline指的是文本基線,改變一下上面的xml代碼,就可以實(shí)現(xiàn)。
<TextView
android:id="@+id/textView1"
.../>
<TextView
android:id="@+id/textView2"
...
app:layout_constraintLeft_toRightOf="@+id/textView1"
app:layout_constraintBaseline_toBaselineOf="@+id/textView1"
/>
可以看到我們讓textview1和textview2的文本基線對齊。
- ConstraintLayout相對定位的用法跟RelativeLayout還是比較相似的,下面用一個(gè)圖來總結(jié)相對定位:
2.2 角度定位
可以以一定角度和距離約束一個(gè)小部件中心相對于另一個(gè)小部件中心。這允許您將一個(gè)小部件定位在一個(gè)圓圈上。
2.2.1 屬性
layout_constraintCircle : 引用另一個(gè)小部件 id
layout_constraintCircleRadius : 到另一個(gè)小部件中心的距離
layout_constraintCircleAngle : 小部件應(yīng)該在哪個(gè)角度(以度為單位,從 0 到
<TextView
android:id="@+id/textView1"
.../>
<TextView
android:id="@+id/textView2"
...
app:layout_constraintCircle="@+id/textView1"
app:layout_constraintCircleAngle="120"
app:layout_constraintCircleRadius="150dp"
/>
指的是TextView2的中心在TextView1的中心的120度,距離為150dp。
2.3 邊距
2.3.1 屬性
android:layout_marginStart //距離開始
android:layout_marginEnd //距離結(jié)束
android:layout_marginLeft //距離左邊
android:layout_marginTop //距離上邊
android:layout_marginRight //距離右邊
android:layout_marginBottom //距離下邊
android:layout_marginBaseline //距離基線
- 看起來跟別的布局沒有什么差別,但實(shí)際上控件在ConstraintLayout里面要實(shí)現(xiàn)margin,必須先約束該控件在ConstraintLayout里的位置,舉個(gè)例子:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<TextView
android:id="@+id/TextView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#E8C99B"
android:gravity="center"
android:text="textview1"
android:textColor="@color/black"
android:textSize="25sp"
android:textStyle="bold"
android:layout_marginLeft="100dp"
android:layout_marginTop="100dp"/>
</android.support.constraint.ConstraintLayout>
我們會發(fā)現(xiàn)textview并沒有距離邊框的左邊和上面有一個(gè)100dp的邊距,在ConstraintLayout里,是不生效的,因?yàn)闆]有約束textview在布局里的位置。
正確的寫法如下:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<TextView
android:id="@+id/TextView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#E8C99B"
android:gravity="center"
android:text="textview1"
android:textColor="@color/black"
android:textSize="25sp"
android:textStyle="bold"
android:layout_marginLeft="100dp"
android:layout_marginTop="100dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
/>
</android.support.constraint.ConstraintLayout>
把textview的左邊和上邊約束到parent的左邊和上邊,這樣margin就會生效,效果如下:
在使用margin的時(shí)候要注意兩點(diǎn):
- 控件必須在布局里約束一個(gè)相對位置
- margin只能大于等于0
2.3.2 不可見性行為(goneMargin)
goneMargin主要用于約束的控件可見性被設(shè)置為gone的時(shí)候使用的margin值,屬性如下:
layout_goneMarginStart //距離開始
layout_goneMarginEnd
layout_goneMarginLeft
layout_goneMarginTop
layout_goneMarginRight
layout_goneMarginBottom
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<TextView
android:id="@+id/textview1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#E8C99B"
android:gravity="center"
android:text="textview1"
android:textColor="@color/black"
android:textSize="25sp"
android:textStyle="bold"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<TextView
android:id="@+id/textView2"
android:layout_width="138dp"
android:layout_height="111dp"
android:background="#D6E1AA"
android:gravity="center"
android:text="textview2"
android:textColor="@color/black"
android:textSize="25sp"
android:textStyle="bold"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toRightOf="@+id/textview1"
/>
</android.support.constraint.ConstraintLayout>
效果如下:
改變一下代碼
- 給textview1添加:
android:visibility="gone"
- textview2的相應(yīng)約束改為:
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toRightOf="@+id/textview1"
app:layout_goneMarginLeft="50dp"
這樣將textview1設(shè)置為不可見后,textview2會距離左邊50dp,效果如下:
2.4 居中和偏移
2.4.1 居中
在RelativeLayout中,把控件放在布局中間的方法是:
android:layout_centerInParent="true"
在Constraintlayout中的寫法是:
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
意思是把控件的上下左右約束在布局的上下左右,這樣就能把控件放在布局的中間了,效果如下。
2.4.2 偏移
layout_constraintHorizontal_bias //水平方向偏移
layout_constraintVertical_bias //垂直方向偏移
效果展示,在xml代碼里再加一句話:
app:layout_constraintHorizontal_bias="0.3"
水平方向距父布局開始位置偏移百分之三十
這時(shí)我們就發(fā)現(xiàn)textvew1已經(jīng)向水平方向上發(fā)生了偏移。
2.5 尺寸約束
2.5.1 約束方式
控件的尺寸可以通過四種不同方式指定:
- 使用指定的尺寸
- 使用wrap_content,讓控件自己計(jì)算大小
當(dāng)控件的高度或?qū)挾葹閣rap_content時(shí),可以使用下列屬性來控制最大、最小的高度或?qū)挾龋?/li>
android:minWidth 最小的寬度
android:minHeight 最小的高度
android:maxWidth 最大的寬度
android:maxHeight 最大的高度
- 使用 0dp (MATCH_CONSTRAINT)
官方不推薦在ConstraintLayout中使用match_parent,可以設(shè)置 0dp (MATCH_CONSTRAINT) 配合約束代替match_parent,舉個(gè)例子:
<TextView
android:id="@+id/TextView1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="50dp"
......
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
寬度設(shè)為0dp,左右兩邊約束parent的左右兩邊,并設(shè)置左邊邊距為50dp,效果如下:
- 寬高比
當(dāng)寬或高至少有一個(gè)尺寸被設(shè)置為0dp時(shí),可以通過屬性layout_constraintDimensionRatio設(shè)置寬高比,舉個(gè)例子:
<TextView
android:id="@+id/TextView1"
android:layout_width="0dp"
android:layout_height="wrap_content"
......
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constrainedWidth="true"
app:layout_constrainedHeight="true"/>
除此之外,在設(shè)置寬高比的值的時(shí)候,還可以在前面加W或H,分別指定寬度或高度限制。 例如:
app:layout_constraintDimensionRatio="H,2:3"指的是 高:寬=2:3
app:layout_constraintDimensionRatio="W,2:3"指的是 寬:高=2:3
-
重要提示:
MATCH_PARENT不建議用于ConstraintLayout. 可以通過MATCH_CONSTRAINT將相應(yīng)的左/右或上/下約束設(shè)置為來定義類似的行為"parent"。
WRAP_CONTENT (添加在 1 . 1中):強(qiáng)制約束
如果維度設(shè)置為WRAP_CONTENT,則在 1.1 之前的版本中,它們將被視為文字維度——也就是說,約束不會限制結(jié)果維度。您可能希望使用WRAP_CONTENT,但繼續(xù)強(qiáng)制執(zhí)行約束以限制結(jié)果維度。在這種情況下,可以添加相應(yīng)的屬性之一:
app:layout_constrainedWidth="true|false"
app:layout_constrainedHeight="true|false"
MATCH_CONSTRAINT維度(添加在 1 . 1中)
當(dāng)維度設(shè)置為MATCH_CONSTRAINT時(shí),默認(rèn)行為是讓結(jié)果大小占用所有可用空間。有幾個(gè)額外的修飾符可用:
- layout_constraintWidth_min和layout_constraintHeight_min
將設(shè)置此維度的最小尺寸- layout_constraintWidth_max和layout_constraintHeight_max
將設(shè)置此維度的最大尺寸- layout_constraintWidth_percent和layout_constraintHeight_percent
將此維度的大小設(shè)置為父維度的百分比
2.6 鏈
如果兩個(gè)或以上控件通過下圖的方式約束在一起,就可以認(rèn)為是他們是一條鏈(圖為橫向的鏈,縱向同理)。
簡單使用,用代碼表示為:
<TextView
android:id="@+id/TextView1"
......
app:layout_constraintHorizontal_chainStyle="spread"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@+id/TextView2" />
<TextView
android:id="@+id/TextView2"
......
app:layout_constraintLeft_toRightOf="@+id/TextView1"
app:layout_constraintRight_toLeftOf="@+id/TextView3"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintRight_toRightOf="parent" />
<TextView
android:id="@+id/TextView3"
......
app:layout_constraintLeft_toRightOf="@+id/TextView2"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintRight_toRightOf="parent" />
三個(gè)textview相互約束,兩端兩textview分別與parent約束,構(gòu)成一條鏈。
每一條鏈的第一個(gè)控件是這條鏈的鏈頭,我們可以在鏈頭中設(shè)置layout_constraintHorizontal_chainStyle屬性改變整條鏈的樣式。
chains提供了3種樣式,分別是:
- spread 展開元素 (默認(rèn))
- spread_inside 展開元素,但鏈的兩端貼近parent
- packet 鏈的元素將被打包在一起。
spread_inside
packet
上面的例子創(chuàng)建了一個(gè)樣式鏈,除了樣式鏈外,還可以創(chuàng)建一個(gè)權(quán)重鏈。
上面所用到的3個(gè)textview寬度都為wrap_content,如果我們把寬度都設(shè)為0dp,這個(gè)時(shí)候可以在每個(gè)texttiew中設(shè)置橫向權(quán)重layout_constraintHorizontal_weight(constraintVertical為縱向)來創(chuàng)建一個(gè)權(quán)重鏈,xml代碼如下:文章來源:http://www.zghlxwxcb.cn/news/detail-806125.html
<TextView
android:id="@+id/TextView1"
android:layout_width="0dp"
......
app:layout_constraintHorizontal_weight="2" />
<TextView
android:id="@+id/TextView2"
android:layout_width="0dp"
......
app:layout_constraintHorizontal_weight="3" />
<TextView
android:id="@+id/TextView3"
android:layout_width="0dp"
......
app:layout_constraintHorizontal_weight="2" />
文章來源地址http://www.zghlxwxcb.cn/news/detail-806125.html
到了這里,關(guān)于Android——ConstraintLayout(約束布局)的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!