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))
}

這個網誌中的熱門文章

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

Android Studio 歷代版本下載點

2022 最新入門零基礎 Flutter教學 【Flutter 程式設計入門實戰 30 天】Flutter 教學課程目錄 (IntelliJ IDEA 開發教學)

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

16天記下7000單字