當我們回頭看我們的 helloworld 範例,會發現我們一直略過一個出現蠻多次的 View
沒有介紹,那就是 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_toTopOf
、Bottom_toBottomOf
、Left_toLeftOf
、Right_toRightOf
、Top_toBottomOf
、Bottom_toTopOf
、Left_toRightOf
、Right_toLeftOf
這些設定 View
間關係的參數,而這些參數的值都是另一個 View
的 id、或是 parent 代表著上層的 View
。
一個完整的 View
必須要有長寬的大小跟 x、y 位置系統才會知道如何描繪這個畫面,而 ConstraintLayout
的真實位置跟大小就是由 layout_width
跟 layout_height
加上這些 constraint 所互相約束出來的。
layout_width
跟 layout_height
通常會有以下幾種值:
wrap_content
:指的是由內容來決定大小。0dp
:指的是不設大小由 constraint 來決定。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
也有提供其他好用的功能可以讓我們更輕易達到某些特定需求。
Circular
Bias
Chains
更多資訊大家可以參考 ConstraintLayout
的官方文件囉!我們下回見!!
https://developer.android.com/reference/android/support/constraint/ConstraintLayout
Android 十全大補已經正式出書上架囉!
有興趣的讀者歡迎參考:
https://www.tenlong.com.tw/products/9789864345786