Jetpack Compose 教學上課講義【從零開始學 Jetpack Compose 程式設計】狀態資料

 

【從零開始學 Jetpack Compose 程式設計】

線上教學課程目錄: https://bit.ly/3JF4SFA
Youtube 課程播放清單:https://bit.ly/3tFjRbx
Udemy 線上課程:https://bit.ly/3MbVnhO


MutableState 三種使用方式

https://developer.android.com/jetpack/compose/state

val mutableState = remember { mutableStateOf(default) }
var value by remember { mutableStateOf(default) }
val (value, setValue) = remember { mutableStateOf(default) }

MutableState 三種差異比較

@Composable
fun Demo() {
    var value1 = remember { mutableStateOf("HKT線上教室") }
    var value2 by remember { mutableStateOf("HKT線上教室") }
    var (value3, setValue) = remember { mutableStateOf("HKT線上教室") }

    Column(Modifier.padding(20.dp)) {
        Text("value1 Demo", fontSize = 20.sp, textDecoration = TextDecoration.Underline)
        Text("value1: $value1")
        Text("value1: ${value1.value}")
        value1.value = "value1 HKT"
        Text("value1: ${value1.value}")

        Spacer(modifier = Modifier.height(50.dp))

        Text("value2 Demo", fontSize = 20.sp, textDecoration = TextDecoration.Underline)
        Text("value2: $value2")
        value2 = "value2 HKT"
        Text("value2: $value2")

        Spacer(modifier = Modifier.height(50.dp))
        
        Text("value3 Demo", fontSize = 20.sp, textDecoration = TextDecoration.Underline)
        Text("value3: $value3")
        value3 = "value3 HKT"
        Text("value3: $value3")
    }
}

remember 和 rememberSaveable 差異比較

螢幕旋轉,activity 重建 rememberSaveable 會保留上一次狀態。

@Composable
fun Demo() {
    var counter1 by remember { mutableStateOf(0) }
    var counter2 by rememberSaveable { mutableStateOf(0) }

    Column(
        modifier = Modifier
            .fillMaxSize()
            .padding(20.dp),
        verticalArrangement = Arrangement.Center,
        horizontalAlignment = Alignment.CenterHorizontally,
    ) {
        Text(
            "counter1: $counter1",
            modifier = Modifier.padding(10.dp),
            fontSize = 30.sp
        )
        Text(
            "counter2: $counter2",
            modifier = Modifier.padding(10.dp),
            fontSize = 30.sp
        )
        Button(
            modifier = Modifier
                .width(150.dp)
                .height(100.dp),
            onClick = {
                counter1++
                counter2++
            }
        ) {
            Text("+1")
        }
    }
}

狀態提升 (State hoisting)

在組合樹中,最高節點聲明,狀態、函數,傳遞給子節點,此行為稱之為狀態提升。
設計子元件,盡量保持無狀態,比較容易共用與測試,資料、函數也比較容易共享。

提升前

@Composable
fun HelloContent1() {
    Column(modifier = Modifier.padding(16.dp)) {
        var name by remember { mutableStateOf("") }
        if (name.isNotEmpty()) {
            Text(
                text = "Hello, $name!",
                modifier = Modifier.padding(bottom = 8.dp),
                style = MaterialTheme.typography.h5
            )
        }
        OutlinedTextField(
            value = name,
            onValueChange = { name = it },
            label = { Text("Name") }
        )
    }
}

狀態提升

@Composable
fun HelloScreen() {
    var name by rememberSaveable { mutableStateOf("") }

    HelloContent2(name = name, onNameChange = { name = it })
}

@Composable
fun HelloContent2(name: String, onNameChange: (String) -> Unit) {
    Column(modifier = Modifier.padding(16.dp)) {
        if (name.isNotEmpty()) {
            Text(
                text = "Hello, $name",
                modifier = Modifier.padding(bottom = 8.dp),
                style = MaterialTheme.typography.h5
            )
        }
        OutlinedTextField(
            value = name,
            onValueChange = onNameChange,
            label = { Text("Name") }
        )
    }
}

本機範圍資料 (CompositionLocal)

https://developer.android.com/jetpack/compose/compositionlocal

CompositionLocal 解決需要層層傳遞狀態問題,函數不用刻意開接口去接收參數,就可以收到資料狀態。且不會更改到原始的初值。

Compose 元件樹

compositionLocalOf 和 staticCompositionLocalOf 差異

//處理較少更新,因為整個下方的狀態數都會被更新
val LocalColor = compositionLocalOf { Color.Red }  

//處理頻繁更新,只更新當前
val LocalColor = staticCompositionLocalOf { Color.Red }
val MyColor = compositionLocalOf { Color.Green }

@Composable
fun Demo() {
    Column (Modifier.padding(20.dp)){
        Composable1()
    }
}

@Composable
fun Composable1() {
    Text("Composable 1", modifier = Modifier.background(MyColor.current))
    Composable2()
}

@Composable
fun Composable2() {
    Text("Composable 2", modifier = Modifier.background(MyColor.current))
    Composable3()
}

@Composable
fun Composable3() {
    Text("Composable 3", modifier = Modifier.background(MyColor.current))
    Composable4()
}

@Composable
fun Composable4() {
    Text("Composable 4", modifier = Modifier.background(MyColor.current))
    CompositionLocalProvider(MyColor provides Color.Blue) {
        Composable5()
    }
    ComposableSub1()
}
@Composable
fun ComposableSub1() {
    Text("ComposableSub 1", modifier = Modifier.background(MyColor.current))
    ComposableSub2()
}
@Composable
fun ComposableSub2() {
    Text("ComposableSub 2", modifier = Modifier.background(MyColor.current))
}

@Composable
fun Composable5() {
    Text("Composable 5", modifier = Modifier.background(MyColor.current))
    Composable6()
}

@Composable
fun Composable6() {
    Text("Composable 6", modifier = Modifier.background(MyColor.current))
}

這個網誌中的熱門文章

nano 文字編輯器

2023 最新入門零基礎 Kotlin教學【從零開始學 Kotlin 程式設計】Kotlin 教學課程目錄 (Android Kotlin, IntelliJ IDEA, Android Studio, Android APP 開發教學)

16天記下7000單字

最新入門零基礎 Java 教學【從零開始學 Java 程式設計】Java教學課程目錄 (IntelliJ IDEA 開發教學)

Android Studio 歷代版本下載點