Android ConstraintLayout佈局

在學習控件的使用之前,瞭解下佈局的相關知識是十分必要的。今天就來看看ConstraintLayout佈局。

ConstraintLayout是Android Studio 2.2中主要的新增功能之一,ConstraintLayout是使用可視化的方式來編寫界面。它的出現主要是爲了解決佈局嵌套過多的問題,以靈活的方式定位和調整小部件。

約束佈局ConstraintLayout 是一個ViewGroup,可以在Api9以上的Android系統使用。ConstraintLayout是採用約束的方式來指定各個控件的位置和關係的。

關鍵聽說阿里都讓使用這玩意。。。。。。

在項目中使用ConstraintLayout

首先,我們的確認在我們項目的build.gradle文件中是否添加了google存儲倉庫,對於使用高一點版本的Android Studio來說這一點不需要擔心。。

在這裏插入圖片描述

下一步在我們app的build.gradle文件中添加ConstraintLayout依賴,這一步新一點的版本我們也不需要去手動添加。。。不放心的可以確認下。

現在ConstraintLayout在我們創建佈局文件的時候已經是默認的佈局了。可想這些事我們都不需要操心了。

在這裏插入圖片描述

如果上面兩個你檢查完了,發現得自己添加的話,那麼再多做一件事情吧。

點解"Sync Project with Gradle Files"進行一下同步吧.

好了,新建一個空的Activity,並勾選生成佈局文件選項,看看出來的佈局文件:

在這裏插入圖片描述

編寫佈局可以拖也可以寫,這裏選擇手寫xml佈局文件。習慣了還是覺得寫的來的快,勿噴。。。

使用相對定位(Relative positioning)

相對定位是我們在ConstraintLayout佈局中很基礎的一種使用姿勢了,使用相對定位允許我們將給定的控件相對於另一個控件進行定位。常見的使用姿勢是:控件給定一側限制爲任何其他控件的另一側。

看個示意圖:

在這裏插入圖片描述

那麼該如何設置呢?

語法格式示例: app:layout_constraintLeft_toRightOf="控件id"
如果目標控件爲父控件則id可以直接寫成parent,否則寫控件的id。

在上面的佈局文件中添加一個Button,不做任何佈局約束。

在這裏插入圖片描述

可用的約束:

layout_constraintLeft_toLeftOf: 當前控件的Left在目標控件的Left上
layout_constraintLeft_toRightOf: 當前控件的Left在目標控件的Right上
layout_constraintRight_toLeftOf: 當前控件的Right在目標控件的Left上
layout_constraintRight_toRightOf: 當前控件的Right在目標控件的Right上
layout_constraintTop_toTopOf: 當前控件的Top在目標控件的Top上
layout_constraintTop_toBottomOf: 當前控件的Top在目標控件的Bottom上
layout_constraintBottom_toTopOf: 當前控件的Bottom在目標控件的Top上
layout_constraintBottom_toBottomOf: 當前控件的Bottom在目標控件的Bottom上
layout_constraintBaseline_toBaselineOf:當前控件的Baseline在目標控件的Baseline上
layout_constraintStart_toEndOf: 當前控件的Start在目標控件的End上
layout_constraintStart_toStartOf: 當前控件的Star在目標控件的Star上
layout_constraintEnd_toStartOf: 當前控件的End在目標控件的Start上
layout_constraintEnd_toEndOf: 當前控件的End在目標控件的End上

上下左右就不多說了,都明白啥意思,start和end這裏給張示意圖大家腦部一下:
在這裏插入圖片描述

首先我們添加一個Button,讓其位於屏幕中央位置:

 <Button
        android:id="@+id/btn1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        android:text="屏幕居中">
    </Button>

在這裏插入圖片描述
當然我們也可以使用left,right來實現水平居方向的約束:

`
<Button
        android:id="@+id/btn1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        android:text="屏幕居中">
    </Button>

在添加兩個Button:

  <Button
        android:id="@+id/btn2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintLeft_toRightOf="@+id/btn1"
        app:layout_constraintBottom_toTopOf="@+id/btn1"
        android:text="按鈕2">
    </Button>

    <Button
        android:id="@+id/btn3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintRight_toLeftOf="@+id/btn1"
        app:layout_constraintTop_toBottomOf="@+id/btn1"
        android:text="按鈕3">
    </Button>

在這裏插入圖片描述

使用Margins

可用列表:

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

我們修改下佈局文件:

    <Button
        android:id="@+id/btn1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="10dp"
        android:layout_marginTop="50dp"
        android:layout_marginRight="50dp"
        android:layout_marginBottom="100dp"
        android:text="按鈕1"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"></Button>

在這裏插入圖片描述

注意:margin屬性需要配合約束來設置,比如你設置了左邊的約束,那麼你就可以使用android:layout_marginStart和android:layout_marginLeft,否則不會生效。

看個例子:

 <Button
        android:id="@+id/btn1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="20dp"
        android:layout_marginRight="50dp"
        android:text="按鈕1"
        app:layout_constraintEnd_toStartOf="@+id/btn2"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        ></Button>

    <Button
        android:id="@+id/btn2"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginLeft="50dp"
        android:layout_marginRight="20dp"
        android:text="按鈕2"
        app:layout_constraintStart_toEndOf="@+id/btn1"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent"></Button>

運行結果:
在這裏插入圖片描述
這裏去掉右邊和btn2的約束,大家再看下效果:

//app:layout_constraintEnd_toStartOf="@+id/btn2"

在這裏插入圖片描述
總之就是一句話,控件和誰有約束,在哪個方向的約束那麼就可以在哪個方向設置Margin。

這裏還有一種情況,那就是我們添加約束的目標控件在某些場合需要隱藏(即設置屬性爲GONE)的時候,我們可指定控件相對於其他控件的邊距。此時需要使用下面的屬性:

layout_goneMarginStart
layout_goneMarginEnd
layout_goneMarginLeft
layout_goneMarginTop
layout_goneMarginRight
layout_goneMarginBottom

看個例子:

 <Button
        android:id="@+id/btn1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="按鈕1"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"></Button>

    <Button
        android:id="@+id/btn2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="按鈕2"
        app:layout_constraintStart_toEndOf="@+id/btn1"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_goneMarginLeft="20dp"></Button>

    <Button
        android:id="@+id/btn3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="按鈕3"
        app:layout_constraintStart_toEndOf="@id/btn2"
        app:layout_constraintTop_toTopOf="parent"></Button>

這裏擺放了三個在一行的按鈕:
在這裏插入圖片描述
將按鈕1的visibility設置爲gone

android:visibility="gone"

此時按鈕2左邊的約束就相對於是parent了,那麼此時按鈕2應該距離左邊20dp:
在這裏插入圖片描述
當然了,實際的使用比這複雜的多, 這裏只希望通過這樣的例子能大概明白是怎麼用的,到了實際使用的時候能夠快速入手。

Bias

首先我們看個例子:

      <Button
        android:id="@+id/btn1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="按鈕1"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent"></Button>

有如上設置的button,那麼這個button到底是怎麼在屏幕顯示的呢?

我剛開始以爲是這個樣子的:
在這裏插入圖片描述
我們想一下start與parent左側對其,end與parent右側對其,那不是相當於設置爲match_parent嗎?可實際上我們給按鈕的寬度設定是wrap_content,也就是說button是沒有辦法向兩邊撐開的。顯然這個猜測是不正確的。

那麼如果我們把layout_width設爲0dp,是不是就能 達到這樣的效果呢?驗證之後發現果然是的。

官方文檔的解釋是:當給控件在水平方向添加相反的約束(當然了是針對同一個target)時,constraintlayout佈局會將控件顯示在target寬度的中間。就像兩個相反的力一樣,使控件兩邊的空白相同。

對於上面的例子來說,就是將按鈕1居中顯示:
在這裏插入圖片描述

遇到上面的情況,我們可能希望按鈕靠左邊顯示,此時我們就需要藉助Bias屬性來進行控制。

可選值:

layout_constraintHorizontal_bias //水平方向偏移
layout_constraintVertical_bias // 垂直方向偏移

這兩個值得取值範圍時:0 ~ 1,默認爲0.5,即居中。不在這個範圍的話,在屏幕中無法顯示出來。

爲按鈕1添加水平方向的偏移,方向時從左到右。

 app:layout_constraintHorizontal_bias="0"

將值設置爲0,意味着我們的控件將在水平方向的左邊開始位置開始顯示。

在這裏插入圖片描述
那麼設置爲1的時候,自然就在最右邊了。
在這裏插入圖片描述

設置爲0.3:

在這裏插入圖片描述

垂直方向就不再演示了,效果一樣的。

Circular positioning

這個該怎麼翻譯呢,直譯的話就是圓形定位。官方給出的解釋大概意思是這樣的;

我們可以相對於一個控件的中心位置,以一定的角度和半徑來約束目標控件的中心位置。

所以我還是將之稱呼爲圓心定位算了,不喜勿怪,英語水平有限。。。

看張示意圖:

在這裏插入圖片描述

簡單來說就是使用圓心定位進行約束,那麼目標控件的中心點一定在以該控件中心,半徑爲n的圓角度爲m的位置處。

可用屬性:

layout_constraintCircle :目標控件id
layout_constraintCircleRadius : 圓半徑
layout_constraintCircleAngle : 角度 (取值: 0 ~ 360)

看個實例:

    <Button
        android:id="@+id/btn1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="按鈕1"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/btn2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="按鈕1"
        app:layout_constraintCircle="@+id/btn1"
        app:layout_constraintCircleAngle="90"
        app:layout_constraintCircleRadius="100dp" />

這裏我們指定半徑爲100dp,然後角度爲90度,也就是和按鈕1的中心點平齊。

在這裏插入圖片描述

Dimensions constraints

尺寸約束,這裏針對的是對ConstraintLayout佈局本身,注意:這些最小和最大尺寸將在ConstraintLayout的尺寸設置爲WRAP_CONTENT時使用。

可用參數;

android:minWidth
android:minHeight
android:maxWidth
android:maxHeight

看個例子:

<?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"
    android:background="@color/colorPrimaryDark"
    tools:context=".QConstraintLayout">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@color/colorAccent"
        android:minWidth="200dp"
        android:minHeight="100dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            android:background="@color/colorPrimaryDark"
            />


    </androidx.constraintlayout.widget.ConstraintLayout>


</androidx.constraintlayout.widget.ConstraintLayout>

在這裏插入圖片描述
實際上這些屬性在將尺寸設置爲match_parent的時候同樣可用,不過存在佈局顯示差異,有興趣的朋友可以試試。

Widgets dimension constraints:控件尺寸約束

我們可通過以下3種不同方式設置android:layout_width和android:layout_height屬性值指定控件的尺寸。

使用指定數值
使用wrap_content
使用0dp,相當於match_constraint

不建議對ConstraintLayout中包含的控件使用MATCH_PARENT。

如果我們在指定 wrap_content屬性的情況下,還想對控件進行特別的約束,那麼可以使用下面的屬性進行設置:

app:layout_constrainedWidth=”true|false”
app:layout_constrainedHeight=”true|false”

這裏在說一下當設置layout_width或者layout_height爲0dp的時候,默認行爲是使結果大小佔用所有可用空間。注意只有兩邊都存在約束的時候才能看到效果哦。

示例:

    <Button
            android:id="@+id/btn1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@color/colorPrimaryDark"
            android:text="測試1"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:background="@color/colorAccent"
            android:text="測試22"
            app:layout_constraintStart_toEndOf="@+id/btn1"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

運行效果:
在這裏插入圖片描述

如果我們去掉右邊的約束:

app:layout_constraintEnd_toEndOf="parent"

在這裏插入圖片描述
看到這裏大家應該清楚該怎麼用了吧。。。要想有效果至少我的有一個寬度和高度讓我去適應吧。。

Ratio

簡單點就是百分比佈局。

使用前提是:ayout_width或者layout_height至少有一個設置爲0dp。

屬性:

layout_constraintDimensionRatio

可選值:

浮點值,表示寬度和高度之間的比率
“寬度:高度”形式的比率,添加H約束高度,添加W約束寬度。

示例:

  <Button
        android:id="@+id/btn1"
        android:layout_width="150dp"
        android:layout_height="0dp"
        android:background="@color/colorPrimaryDark"
        android:text="測試1"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintDimensionRatio="H,1:3"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/btn2"
        android:layout_width="150dp"
        android:layout_height="0dp"
        android:background="@color/colorAccent"
        android:text="測試22"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintDimensionRatio="W,1:3"
        app:layout_constraintTop_toTopOf="@+id/btn1" />

效果圖:

在這裏插入圖片描述

Chains

在橫軸或或者豎軸上的控件相互約束時,可以組成一個鏈式約束。鏈在單個軸(水平或垂直)上提供類似行的行爲。另一個軸可以獨立約束。

在這裏插入圖片描述

如果一組控件通過雙向連接鏈接在一起,則它們被視爲鏈。鏈由鏈的第一個元素(鏈的“頭部”)上設置的屬性控制.鏈頭是水平鏈的最左側控件,垂直鏈的最頂部控件。

這裏是引用

可用屬性:

app:layout_constraintHorizontal_chainStyle
app:layout_constraintVertical_chainStyle

可選值:

spread模式:元素將展開(默認樣式);
spread_inside模式: 類似spread模式,但鏈的端點不會分散;
含有權重spread模式:如果設置了某個或某些控件MATCH_CONSTRAINT(0dp),這個或這些控件將分割可用空間;
packed模式:鏈條的元素將被包裝在一起。然後,子項的水平或垂直偏差屬性將影響打包元素的定位;

下圖是各種取值的表現形式。

在這裏插入圖片描述

在這裏插入圖片描述

具體示例就貼出來了。

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