之前测试过dataBinding绑定数据,再试下compose绑定数据。
Kotlin
package com.example.testcompose1
import android.os.Bundle
import android.widget.Toast
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material3.Button
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.TextField
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.platform.LocalContext
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContent {
todoJobList()
}
}
}
@Preview
@Composable
fun todoJobList() { // 显示待办事项
val context = LocalContext.current
// 使用 remember 和 mutableStateOf 保存输入框的文本
var text by remember { mutableStateOf("") }
// 使用 mutableStateListOf 保存待办项列表
val todoItems = remember { mutableStateListOf<String>() }
Column(modifier = Modifier.padding(16.dp)) {
// 文本输入框
TextField(
value = text,
onValueChange = { text = it }, // 反向绑定,视图变化--> 数据变化
label = { Text("输入待办事项") },
modifier = Modifier.fillMaxWidth()
)
// 添加按钮
Button(
onClick = {
if (text.isNotBlank()) {
println("添加:$text")
Toast.makeText(context, "添加:$text", Toast.LENGTH_SHORT).show()
todoItems.add(text) // 添加到列表
text = "" // 清空输入. 测试正向绑定,数据状态变化--> 视图变化
}
},
modifier = Modifier.padding(top = 8.dp)
) {
Text("添加")
}
// 显示待办列表
Spacer(modifier = Modifier.height(16.dp))
Text("待办列表", style = MaterialTheme.typography.titleMedium)
LazyColumn {
items(items = todoItems) { item ->
TodoItem(item = item)
}
}
}
}
@Composable
fun TodoItem(item: String) {
Text(
text = item,
modifier = Modifier
.fillMaxWidth()
.padding(vertical = 8.dp)
)
}
运行:

可以随便输入点什么点击添加,会添加到下面的列表中:

ok. mutableStateOf能创建可观察状态的数据,值变化的时候重组刷新页面。remember能让状态重组时记住之前的值,不被重置。
每一条数据旁再添加个删除按钮。
修改下TodoItem函数,增加一个删除按钮,删除函数由onDelete参数传入:
Kotlin
@Composable
fun TodoItem(item: String, onDelete: () -> Unit // 添加删除回调,删除逻辑放在上层。即把回调传给里面的按钮。
) {
Row(
modifier = Modifier
.fillMaxWidth()
.padding(vertical = 8.dp),
horizontalArrangement = Arrangement.SpaceBetween // 横向布局子元素两端对齐,剩余空白空间平均分配到子元素之间
) {
Text(text = item)
IconButton(onClick = onDelete) {
Icon(Icons.Default.Delete, contentDescription = "删除")
}
}
}
再修改下todoJoblist函数,将删除函数传给子组件:

修改完完整代码:
Kotlin
package com.example.testcompose1
import android.os.Bundle
import android.widget.Toast
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Delete
import androidx.compose.material3.Button
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.TextField
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.platform.LocalContext
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContent {
todoJobList()
}
}
}
@Preview
@Composable
fun todoJobList() {
val context = LocalContext.current
// 使用 remember 和 mutableStateOf 保存输入框的文本
var text by remember { mutableStateOf("") }
// 使用 mutableStateListOf 保存待办项列表
val todoItems = remember { mutableStateListOf<String>() }
Column(modifier = Modifier.padding(16.dp)) {
// 文本输入框
TextField(
value = text,
onValueChange = { text = it }, // 反向绑定,视图变化--> 数据变化
label = { Text("输入待办事项") },
modifier = Modifier.fillMaxWidth()
)
// 添加按钮
Button(
onClick = {
if (text.isNotBlank()) {
println("添加:$text")
Toast.makeText(context, "添加:$text", Toast.LENGTH_SHORT).show()
todoItems.add(text) // 添加到列表
text = "" // 清空输入. 测试正向绑定,数据状态变化--> 视图变化
}
},
modifier = Modifier.padding(top = 8.dp)
) {
Text("添加")
}
// 显示待办列表
Spacer(modifier = Modifier.height(16.dp))
Text("待办列表", style = MaterialTheme.typography.titleMedium)
LazyColumn {
items(items = todoItems) { item ->
TodoItem(item = item
, onDelete = { todoItems.remove(item) }) // 点击时从列表中删除
}
}
}
}
@Composable
fun TodoItem(item: String, onDelete: () -> Unit // 添加删除回调,删除逻辑放在上层。即把回调传给里面的按钮。
) {
Row(
modifier = Modifier
.fillMaxWidth()
.padding(vertical = 8.dp),
horizontalArrangement = Arrangement.SpaceBetween // 横向布局子元素两端对齐,剩余空白空间平均分配到子元素之间
) {
Text(text = item)
IconButton(onClick = onDelete) {
Icon(Icons.Default.Delete, contentDescription = "删除")
}
}
}
测试下,添加几条数据:

删除一个:

ok. 状态管理没问题。