約束佈局ConstraintLayout使用詳解

Android Studio 2.3起,官方的模板默認使用 ConstraintLayoutConstraintLayout 官方文檔,之前項目中用的比較少,有些屬性不是很熟練,做個筆記方便查找

相對定位的常用屬性:

layout_constraintLeft_toLeftOf
layout_constraintLeft_toRightOf
layout_constraintRight_toLeftOf
layout_constraintRight_toRightOf
layout_constraintTop_toTopOf
layout_constraintTop_toBottomOf
layout_constraintBottom_toTopOf
layout_constraintBottom_toBottomOf
layout_constraintBaseline_toBaselineOf
layout_constraintStart_toEndOf
layout_constraintStart_toStartOf
layout_constraintEnd_toStartOf
layout_constraintEnd_toEndOf

注意點:

  1. 對於一個view,使用佈局必須要設置水平方向及垂直方向的定位屬性,不然會報錯。
  2. 設置同一方向設置,比如水平方向,僅設置constraintLeft則會爲左對齊,僅設置constraintRight則會右對齊,兩者都設置默認居中對齊。如果不想居中對齊,則需要設置屬性layout_constraintHorizontal_bias範圍爲0~1,默認居中爲0.5.
    layout_constraintVertical_bias 垂直偏移

兩個TextView的高度不一致,但是又希望他們文本對齊,這個時候就可以使用layout_constraintBaseline_toBaselineOf

邊距

常用margin ConstraintLayout的邊距常用屬性如下:

android:layout_marginStart
android:layout_marginEnd
android:layout_marginLeft
android:layout_marginTop
android:layout_marginRight
android:layout_marginBottom

我們只有設置了相應的約束margin纔有效,如設置了layout_constraintLeft_toLeftOf或者
layout_constraintLeft_toRightOflayout_marginLeft纔會生效。

goneMargin

goneMargin主要用於約束的控件可見性被設置爲gone的時候,使用的margin值是否有效,屬性如下:

layout_goneMarginStart
layout_goneMarginEnd
layout_goneMarginLeft
layout_goneMarginTop
layout_goneMarginRight
layout_goneMarginBottom

尺寸約束

控件的尺寸可以通過四種不同方式指定:

1. 使用指定的尺寸

2.使用wrap_content,讓控件自己計算大小

當控件的高度或寬度爲wrap_content時,可以使用下列屬性來控制最大、最小的高度或寬度:
android:minWidth 最小的寬度
android:minHeight 最小的高度
android:maxWidth 最大的寬度
android:maxHeight 最大的高度
注意!當ConstraintLayout爲1.1版本以下時,使用這些屬性需要加上強制約束,如下所示:
app:constrainedWidth=”true”
app:constrainedHeight=”true”

3.使用 0dp (MATCH_CONSTRAINT)

官方不推薦在ConstraintLayout中使用match_parent,可以設置 0dp (MATCH_CONSTRAINT) 配合約束代替match_parent

4.寬高比

當寬或高至少有一個尺寸被設置爲0dp時,可以通過屬性layout_constraintDimensionRatio設置寬高比

app:layout_constraintDimensionRatio="H,2:3"指的是 高:寬=2:3
app:layout_constraintDimensionRatio="W,2:3"指的是 寬:高=2:3

如果兩個或以上控件通過下圖的方式約束在一起,就可以認爲是他們是一條鏈(圖爲橫向的鏈,縱向同理)。

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        >

    <TextView
            android:id="@+id/text1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:padding="10dp"
            android:text="text1"
            android:background="@color/colorAccent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintEnd_toStartOf="@id/text2"
            app:layout_constraintHorizontal_chainStyle="spread"
            app:layout_constraintTop_toTopOf="parent" />

    <TextView
            android:id="@+id/text2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:padding="10dp"
            android:text="text2"
            android:background="@color/colorPrimary"
            app:layout_constraintStart_toEndOf="@id/text1"
            app:layout_constraintEnd_toStartOf="@id/text3"
            app:layout_constraintTop_toTopOf="parent" />
    <TextView
            android:id="@+id/text3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:padding="10dp"
            android:text="text3"
            android:background="#921"
            app:layout_constraintStart_toEndOf="@id/text2"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

layout_constraintHorizontal_chainStyle默認爲spread,效果如圖

另外兩個取值packed

spread_inside

輔助工具

Guideline

Guildline是一條輔助線,幫助你完成佈局但它不會顯示在界面上。
Guildline的主要屬性:
android:orientation :垂直vertical,水平horizontal
layout_constraintGuide_begin 指定位置距離開始
layout_constraintGuide_end 指定位置距離結束
layout_constraintGuide_percent 距離頂部的百分比(orientation = horizontal時則爲距離左邊)

Barrier

假設有3個控件ABC,C在AB的右邊,但是AB的寬是不固定的,這個時候C無論約束在A的右邊或者B的右邊都不對。當出現這種情況可以用Barrier來解決。Barrier可以在多個控件的一側建立一個屏障,如下所示:


<?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">

    <TextView
            android:id="@+id/text1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@color/colorAccent"
            android:padding="10dp"
            android:text="text1"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

    <TextView
            android:id="@+id/text2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@color/colorPrimary"
            android:padding="10dp"
            android:text="this is the text2"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@id/text1" />


    <androidx.constraintlayout.widget.Barrier
            android:id="@+id/barrier"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:barrierDirection="right"
            app:constraint_referenced_ids="text1,text2" />

    <TextView
            android:id="@+id/text3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="#872"
            android:padding="10dp"
            android:text="text3"
            app:layout_constraintLeft_toRightOf="@+id/barrier" />

</androidx.constraintlayout.widget.ConstraintLayout>

效果如下


app:barrierDirection爲屏障所在的位置,可設置的值有:bottomendleftrightstarttop
app:constraint_referenced_ids爲屏障引用的控件,可設置多個,用“,”隔開

Group

Group可以把多個控件歸爲一組,方便隱藏或顯示一組控件,舉個例子:

<android.support.constraint.Group
        android:id="@+id/group"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:visibility="invisible"
        app:constraint_referenced_ids="text1,text3" />

設置groupvisibilityinvisible,則text1與text3均不可見。

Placeholder

Placeholder指的是佔位符,可以定義一個位置,當給Placeholder使用setContentId()設置另一個控件的id,使這個控件移動到佔位符的位置了

<?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">

    <Button
            android:id="@+id/left_btn"
            android:layout_width="wrap_content"
            android:layout_height="50dp"
            android:background="#ffff0000"
            android:text="left_top"
            android:textColor="@android:color/white"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            android:onClick="clickview"
            />

    <Button
            android:id="@+id/right_btn"
            android:layout_width="wrap_content"
            android:layout_height="50dp"
            android:background="#ffff0000"
            android:text="right_top"
            android:textColor="@android:color/white"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            android:onClick="clickview"/>

    <Button
            android:id="@+id/left_bot_btn"
            android:layout_width="wrap_content"
            android:layout_height="50dp"
            android:background="#ffff0000"
            android:text="left_bot"
            android:textColor="@android:color/white"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            android:onClick="clickview"/>
    <Button
            android:id="@+id/right_bot_btn"
            android:layout_width="wrap_content"
            android:layout_height="50dp"
            android:background="#ffff0000"
            android:text="right_bot"
            android:textColor="@android:color/white"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintBottom_toBottomOf="parent"
            android:onClick="clickview"/>

    <androidx.constraintlayout.widget.Placeholder
            android:id="@+id/place_holder"
            android:layout_width="wrap_content"
            android:layout_height="50dp"
            android:background="#ffff0000"
            android:text="right"
            android:textColor="@android:color/white"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            />

</androidx.constraintlayout.widget.ConstraintLayout>

在Activity中設置

placeholder=findViewById(R.id.place_holder);

public void clickview(View view){
        placeholder.setContentId(view.getId());
    }

實現點擊四個角的那一個按鈕,那麼該按鈕就會顯示在正中間

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章