iT邦幫忙

第 11 屆 iT 邦幫忙鐵人賽

DAY 8
0

當我們回頭看我們的 helloworld 範例,會發現我們一直略過一個出現蠻多次的 View 沒有介紹,那就是 ConstraintLayout

ConstraintLayout

ConstraintLayout 是一個非常特別的 ViewGroup,Android layout 原本設計的概念是透過很多層相對單純 的 ViewGroup 組合成複雜的畫面。好處是每層邏輯比較簡單,但有時候因為太多層的嵌套反倒有效能的問題。

ConstraintLayout 的出現顛覆了這個概念,ConstraintLayout 非常強大可以設定每個子 View 的相對關係,所以 layout 的就不會有很多層的存在。

首先,請特別注意 ConstraintLayout 並不是原生 Android 所提供的 View,一般來說我們必須另外在 build.gradle 加上這一行 import:

dependencies {
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
}

因為我們在建立 project 的時候使用了 template 所以 Android Studio 自動幫我們做了這一個步驟,如果是已經存在的 project 而使用 ConstraintLayout 有問題的時候可以檢查一下是不是這個問題。

確認完 import 的問題後我們回顧一下 activity_main.xml 尋找怎麼使用 ConstraintLayout 的線索:

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

    <Button
        android:id="@+id/myButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Click"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

我們會發現很多諸如 Top_toTopOfBottom_toBottomOfLeft_toLeftOfRight_toRightOfTop_toBottomOfBottom_toTopOfLeft_toRightOfRight_toLeftOf 這些設定 View 間關係的參數,而這些參數的值都是另一個 View 的 id、或是 parent 代表著上層的 View

一個完整的 View 必須要有長寬的大小跟 x、y 位置系統才會知道如何描繪這個畫面,而 ConstraintLayout 的真實位置跟大小就是由 layout_widthlayout_height 加上這些 constraint 所互相約束出來的。

layout_widthlayout_height 通常會有以下幾種值:

  1. wrap_content:指的是由內容來決定大小。
  2. 0dp:指的是不設大小由 constraint 來決定。
  3. 或是其他具體的值,如:48dp、16dp 等。

p.s 如果對 dp、px、sp 等不太熟悉可以看一下這個文件。https://developer.android.com/training/multiscreen/screendensities

如果一個 View 的寬度是 0dp 的時候就需要左右二邊的 constraint 來限制出正確的寬度,而如果寬度是具體的值或是 wrap_content 就只需要一邊的 constraint。高度也是一樣的邏輯。

我們再回頭解釋我們的 Button,對於四邊都是撐開到最大,但寬高不為 0dp,所以寬高會固定不會撐開,那 x、y 位置又要怎麼算呢?

<Button
    android:id="@+id/myButton"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Click"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintTop_toTopOf="parent" />

大家可以想像一下四邊的 constraint 就像條橡皮筋ㄧ樣,當沒有其他作用力的情形之下,這個 Button 的位置會在哪裡呢?

以 x 方向來說,因為左右的力互相制衡且受一樣大的力,所以左右二條橡皮筋拉長的長度會一樣,也就是說這個 Button 會左右置中。高度也是同裡,所以我們會看到 Button 一直在畫面的正中央。

幾乎一半以上的 layout 都可以用這些 constraint 來相互約束算出來,但 ConstraintLayout 也有提供其他好用的功能可以讓我們更輕易達到某些特定需求。

  1. Circular

  2. Bias

  3. Chains

更多資訊大家可以參考 ConstraintLayout 的官方文件囉!我們下回見!!
https://developer.android.com/reference/android/support/constraint/ConstraintLayout


上一篇
[Android 十全大補] Activitys
下一篇
[Android 十全大補] RecyclerView
系列文
Android 十全大補30

尚未有邦友留言

立即登入留言