iT邦幫忙

2022 iThome 鐵人賽

DAY 18
0

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


remember 會把物件儲存在 Composition 內,當 recomposition 期間 remember 所在的 scope 沒有再度被呼叫時,則會清除該物件。

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

https://ithelp.ithome.com.tw/upload/images/20220907/20151958vXuPLv4aki.png 立馬下載

為了將這個行為以視覺化呈現,我們要在 app 內實作以下功能:如果使用者今天發了脾氣,就顯示一項可以「緩和情緒的任務」給使用者去做,而使用者也能選擇關閉任務。因為 composables 應該精簡且可供重複使用,我們來建立新的 composable 並命名為 WellnessTaskItem,讓這個 composable 將收到的 string 當做參數,並按照這個參數顯示「情緒緩和任務」,以及一個「關閉」圖示按鈕。

我們來建立新檔案 WellnessTaskItem.kt 並加入以下程式碼。我們在後續步驟中將會用到這個 composable function。

import androidx.compose.foundation.layout.Row
import androidx.compose.material.Icon
import androidx.compose.material.IconButton
import androidx.compose.material.Text
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Close
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.compose.foundation.layout.padding

@Composable
fun WellnessTaskItem(
    modifier: Modifier = Modifier,
    taskName: String,
    onClose: () -> Unit
) {
    Row(
        modifier = modifier, verticalAlignment = Alignment.CenterVertically
    ) {
        Text(
            modifier = Modifier.weight(1f).padding(start = 16.dp),
            text = taskName
        )
        IconButton(onClick = onClose) {
            Icon(Icons.Filled.Close, contentDescription = "Close")
        }
    }
}

WellnessTaskItem 函式會接收「任務名稱」,以及 onClose lambda 函式做為參數 (就像內建的 Button composable 接收 onClick 一樣)。

WellnessTaskItem 看起來會像這樣:

接著,我們來實作 AngryCounter 以便在 count > 0 時顯示 WellnessTaskItem

count 大於 0 時,定義變數 showTask 藉此定義是否要顯示 WellnessTaskItem,並初始化為 true

我們用 if 來判斷,在 showTasktrue 的時候顯示 WellnessTaskItem。運用我們前幾天學到的 remember API 來確定 recomposition 後依然可以保留 showTask

@Composable
fun AngryCounter() {
   Column(modifier = Modifier.padding(16.dp)) {
       var count by remember { mutableStateOf(0) }
       if (count > 0) {
           var showTask by remember { mutableStateOf(true) }
           if (showTask) {
               WellnessTaskItem(
                   onClose = { },
                   taskName = "Take it easy, take a deep breath"
               )
           }
           Text("You've got angry $count times today.")
       }

       Button(onClick = { count++ }, enabled = count < 10) {
           Text("I feel Anger!")
       }
   }
}

我們要來使用 WellnessTaskItemonClose lambda 函式,當有人按下 X 按鈕時,不要顯示任務,並將 showTask 變數更改為 false

...
   WellnessTaskItem(
      onClose = { showTask = false },
      taskName = "Take it easy, take a deep breath"
   )
...

接下來請新增一個 Button,寫上文字「Clear angry count」(清除生氣次數),然後把它放在「I feel Anger!」(我感到怒怒) Button 旁邊。我們可以使用 Row 來對齊這兩個按鈕。也可以在 Row 加入 padding。當有人按下「Clear angry count」(清除生氣次數) 的按鈕後,變數 count 就會重設為 0

我們的 AngryCounter composable function 應該會像下面這樣:

import androidx.compose.foundation.layout.Row


@Composable
fun AngryCounter(modifier: Modifier = Modifier) {
   Column(modifier = modifier.padding(16.dp)) {
       var count by remember { mutableStateOf(0) }
       if (count > 0) {
           var showTask by remember { mutableStateOf(true) }
           if (showTask) {
               WellnessTaskItem(
                   onClose = { showTask = false },
                   taskName = "Take it easy, take a deep breath"
               )
           }
           Text("You've got angry $count times today.")
       }

       Row(Modifier.padding(top = 8.dp)) {
           Button(onClick = { count++ }, enabled = count < 10) {
               Text("I feel Anger!")
           }
           Button(onClick = { count = 0 }, Modifier.padding(start = 8.dp)) {
               Text("Clear angry count")
           }
       }
   }
}

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

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

https://ithelp.ithome.com.tw/upload/images/20220907/20151958vXuPLv4aki.png 立馬下載

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


上一篇
頗析 Composition 中的 composable
下一篇
Composition 中的 remember
系列文
Kimoji:以 Jetpack Compose 實作一款「心情日記」應用30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言