iT邦幫忙

2025 iThome 鐵人賽

DAY 7
0
Mobile Development

現代Android jetpack compose開發入門系列 第 7

Day 7:狀態儲存,能保留狀態的輸入框

  • 分享至 

  • xImage
  •  

前篇提到了輸入型的UI元件,但是發現無法正確的反饋結果與改變顯示,這時就需要remember與mutableState來接收並顯示輸入

@Composable  
fun App(modifier: Modifier = Modifier) {  
    Column {  
        Text("Ok")  
        Icon(Icons.Default.FavoriteBorder, "")  
        TextField(  
            value = "nothing",  
            onValueChange = {it-> //可省略  
                Log.d("TextField", "App: $it")  
            },  
            label = {Text("TextField")}  
        )  
        Button(  
            onClick = {  
                Log.d("Button", "App: pressed")  
            }  
        ) {  
            Text("Button")  
        }  
    }
}

這是目前的程式

狀態保留的必要

在 UI 開發中,你可能會想:「為什麼不直接用一個一般的變數來存放資料,再在需要的地方讀取就好?」
但實際上,這樣做的話 UI 並不會自動更新

Compose 的核心概念是「聲明式 UI」:畫面顯示的內容,取決於狀態(State)。

  • 當你在 UI 中「讀取」一個狀態值(get),這個元件就會記住自己依賴了它。

  • 當這個狀態值「被改變」(set)時,Compose 會自動重新執行相關的 Composable,讓畫面顯示最新的狀態。

換句話說,狀態不只是「存放資料」而已,它還負責「觸發 UI 更新」。
這也是為什麼我們需要 remember { mutableStateOf(...) },而不是只用一般變數。

添加計數器

在App底下加入這一行

var counter by remember { mutableStateOf(0) }

Kotlin語法糖:by 是一個快速設定get與set value的方法,請手動將by需要的函數import

然後在按鈕按下的時候讓counter++,這樣就有了可以改變的counter,但是還需要有元件來顯示
所以改造一下Text
應該會長這樣:

@Composable  
fun App(modifier: Modifier = Modifier) {  
    var counter by remember { mutableStateOf(0) }  
    Column(  
        modifier = Modifier.fillMaxSize(),  
        horizontalAlignment = Alignment.CenterHorizontally,  
        verticalArrangement = Arrangement.Center //美化排版
    ) {  
        Text("Pressed $counter times")  
        // ......
        Button(  
            onClick = {  
                // Log.d("Button", "App: pressed")  
                counter++  
            }  
        ) {  
            Text("Button")  
        }  
    }
}

現在按鈕按下後,Text的數字會往上增加

保留TextField輸入

這是最最常用的功能與寫法,與上面同樣,可以用mutableStateOf("")來儲存字串內容

var inputString by remember { mutableStateOf("") }
TextField(  
    value = inputString,  
    onValueChange = {it-> //可省略  
        inputString = it  
    },  
    label = {Text("TextField")}  
)

這樣子就有一個可以輸入的輸入框了


上一篇
Day 6:美化介面排版
系列文
現代Android jetpack compose開發入門7
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言