iT邦幫忙

2022 iThome 鐵人賽

DAY 12
0

https://ithelp.ithome.com.tw/upload/images/20220912/20151958IFjRs0xIZ4.png Medium 好讀版


在 Composable functions 裡,如果有 state 會由多個函式讀取或修改,就應該放在 common ancestor 裡面,這個過程稱為「state hoisting」。「hoist」的意思就是「抬高」或「提高」。

此系列文章是以我的業餘專案: Kimoji 作為範例。
這款以純 Jetpack Compose 撰寫的 side project,已經在 Google Play 上架。 歡迎試玩!

https://ithelp.ithome.com.tw/upload/images/20220907/20151958vXuPLv4aki.png 立馬下載 https://ithelp.ithome.com.tw/upload/images/20220907/20151958LtM1NGErzK.png 索取兌換碼

藉由 state hoisting,可以避免因為有太多重複的 state 而產生 bug,也可以讓我們更能重複利用 composables,還能讓 composables 更容易進行測試。而相反地,如果有 state 不需要由 composable 的 parent 管理,則我們就不應該 hoist 這些 state。簡單來說,Source of truth 屬於建立和管理 state 的人。

舉個例子,我們可以在 app 裡建立一個 onboarding 畫面。

MainActivity.kt 加入以下程式碼:

import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.runtime.getValue
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.foundation.layout.Arrangement

...

@Composable
fun OnboardingScreen() {
    // TODO: This state should be hoisted
    var shouldShowOnboarding by remember { mutableStateOf(true) }

    Surface {
        Column(
            modifier = Modifier.fillMaxSize(),
            verticalArrangement = Arrangement.Center,
            horizontalAlignment = Alignment.CenterHorizontally
        ) {
            Image(
                painter = painterResource(R.drawable.joy),
                contentDescription = null,
                modifier = Modifier
                    .padding(vertical = 24.dp)
                    .size(40.dp)
                    .clip(CircleShape)
            )
            Text("Welcome to the Kimoji!")
            Button(
                modifier = Modifier.padding(vertical = 24.dp),
                onClick = { shouldShowOnboarding = false }
            ) {
                Text("Hi, Kimoji!")
            }
        }
    }
}

@Preview(showBackground = true, widthDp = 320, heightDp = 320)
@Composable
fun OnboardingPreview() {
    KimojiTheme {
        OnboardingScreen()
    }
}

我們來看看這段程式碼裡面的功能:

  • 我們已經新增了 OnboardingScreen 的 composable 以及新的預覽畫面。如果我們 build project,就會發現同時會出現多個預覽畫面。我們也在 preview 加入了固定的寬高,以便檢查內容是否可以正確對齊。
  • 我們可以設定 Column 來讓內容顯示在螢幕中央。
  • shouldShowOnboarding 使用的是 by keyword,而不是 =。這是 property delegate,讓我們可以不用每次都打 .value 來存取 state。
  • 當使用者點擊按鈕時,shouldShowOnboarding 會設為 false,但是我們還沒有從任何地方讀取這個 state。

明天我們會繼續在 app 裡加入 onboarding 畫面。目標是在啟動 app 時顯示此畫面,並在使用者按下「Hi, Kimoji」 之後隱藏畫面。

此系列文章是以我的業餘專案:Kimoji 為範例。

Kimoji 是一款心情日記 App,讓你用可愛的 emoji 來撰寫你的心情日記。現在就來試試這款設計精美的微日記吧!

https://ithelp.ithome.com.tw/upload/images/20220907/20151958vXuPLv4aki.png 立馬下載 https://ithelp.ithome.com.tw/upload/images/20220907/20151958LtM1NGErzK.png 索取兌換碼

Reference: https://developer.android.com/codelabs/jetpack-compose-basics


上一篇
Composable functions 可以平行執行
下一篇
State hoisting 的例子
系列文
Kimoji:以 Jetpack Compose 實作一款「心情日記」應用30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言