關於我為什麼突然開始學Compose,我有幾點想說。
首先,Jetpack Compose是2019年釋出的新一代Android UI Framework,取代了之前傳統的XML,並且已經演化穩定,現在更是Android開發的預設UI Framework。這個Framework還正年輕,前途不可限量。
其次,JB公司新釋出的Kotlin Multiplatform也終於開始支援使用Compose進行多平台的UI開發了,這樣子結合起之前釋出的KMM,Kotlin做多平台似乎變得更加優雅了。由於Android設計師可以可以毫無壓力轉到Kotlin Multiplatform,我個人認為,它日後將成為取代Flutter的一把利刃。
還有就是它的這種UI宣告方式,是使用lambda表達式做引數來進行巢狀UI元件的構建,雖然這相對於Flutter來講是一個小小的改動(當然只是看起來,一個函式一個型別建構子,想想都知道是天差地遠),但是在我的觀念裡,這真的有變得更加合理了。真的比Flutter那種什麼都塞到建構子裏的方法來得更優雅,也更符合直覺。
Composable Functions
在Compose中,使用@composable
annotation標註的函式即為Composable functions。這類函式被用來描述UI的階層。比如:
1 |
|
在MainActivity的setContent()
函式中,不需要再像以前那樣使用xml來定義UI,而是直接呼叫已經定義的composable函式即可。
1 | class MainActivity : AppCompatActivity() { |
我們可以看到Compose提供的UI元件有一部分是容器類的,即最後一個引數是函式。於是我們可以使用lambda表達式來表示巢狀結構。
@Preview annotation
使用@Preview
這個annotation可以實現預覽composable的元件。必須有這樣一個annotation,否則無論是預覽窗還是AVD,都不會有顯示,甚至會有報錯。
Modifier
大部分的Compose UI元件,都會提供一個引數名為modifier
,可以傳入一個Modifier類型的函式。這個引數用於修飾元素的顯示狀態,即Web開發中的CSS。你可以吧該引數看作是HTML元素的style
。
1 |
|
Layout
Compose提供三個元件,分別是Column
、Row
和Box
。這三個元件是基本的版面配置元件。
1 | import androidx.compose.foundation.layout.Row |
Compose狀態管理
對於一個Web開發人員,尤其是對於一個有學習過Vue.js和React的Web開發人員來講,狀態管理這個概念實在是不應該陌生。
在Vue.js中,使用有狀態的變數,應該使用ref()
或reactive()
函式包圍,然後使用<name>.value
來呼叫它。
在Compose中,有異曲同工之妙。在Compose中,我們這樣定義有狀態的變數:
1 | val expanded = remember { mutableStateOf(false) } |
然後一樣使用expanded.value
去呼叫它就好了。
定義式可以做如下解釋:
mutableStateOf()
函式:標記該變數是一個有狀態的變數。remember {}
:記住該變數的狀態,防止更新元件的時候該變數被重置。
狀態提升
在Compose中的狀態提升幾乎和在React中一模一樣。都是把狀態變數放到共同的父元素中,然後透過函式的向下呼叫來修改父元素中的狀態。
給一個例子,這應該非常熟悉了:
1 |
|
使用Kotlin的by
委派功能,我們可以避免每次都使用值,這是一種推薦的做法。
狀態保留
如果我們希望在執行、旋轉畫面、變更為深色模式,或是終止程序之後,都能夠保留狀態,我們僅需要把remember {}
變成rememberSavable{}
即可。