Jetpack Compose 教學上課講義【從零開始學 Jetpack Compose 程式設計】狀態資料
【從零開始學 Jetpack Compose 程式設計】
線上教學課程目錄: https://bit.ly/3JF4SFA
Youtube 課程播放清單:https://bit.ly/3tFjRbx
Udemy 線上課程:https://bit.ly/3MbVnhO
【從零開始學 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))
}