ComposeHooks
ComposeHooks copied to clipboard
useReducer当遇到mutableStateListOf时候怎么办?
useReducer默认用mutableStateOf实现,我现在想用mutableStateListOf。
需求来自:https://zh-hans.react.dev/learn/scaling-up-with-reducer-and-context
package com.example.myapplication.task1
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.width
import androidx.compose.material3.Button
import androidx.compose.material3.Checkbox
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.material3.TextField
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.key
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import com.example.myapplication.ui.theme.MyApplicationTheme
class TaskDemo : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
MyApplicationTheme {
// A surface container using the 'background' color from the theme
Surface(modifier = Modifier.fillMaxSize(), color = MaterialTheme.colorScheme.background) {
TaskApp()
}
}
}
}
}
@Composable
fun TaskList(tasks: List<Task>, onChangeTask: (Task) -> Unit, onDeleteTask: (Int) -> Unit) {
tasks.forEach { task ->
key(task.id) {
TaskItem(task = task, onChange = onChangeTask, onDelete = onDeleteTask)
}
}
}
@Composable
fun TaskItem(task: Task, onChange: (Task) -> Unit, onDelete: (Int) -> Unit) {
var isEditing by remember { mutableStateOf(false) }
var text by remember { mutableStateOf(task.text) }
Row(verticalAlignment = Alignment.CenterVertically) {
Checkbox(
checked = task.done,
onCheckedChange = { checked ->
onChange(task.copy(done = checked))
}
)
if (isEditing) {
TextField(
modifier = Modifier.width(100.dp),
value = text,
onValueChange = { newText ->
text = newText
onChange(task.copy(text = newText))
}
)
Button(onClick = { isEditing = false }) {
Text("Save")
}
} else {
Text(text = task.text)
Button(onClick = { isEditing = true }) {
Text("Edit")
}
}
Button(onClick = { onDelete(task.id) }) {
Text("Delete")
}
}
}
data class Task(val id: Int, var text: String, var done: Boolean)
@Composable
fun AddTask(onAddTask: (String) -> Unit) {
var text by remember { mutableStateOf("") }
Row {
TextField(
modifier = Modifier.width(100.dp),
value = text,
onValueChange = { newText ->
text = newText
},
placeholder = { Text("Add task") }
)
Button(onClick = {
onAddTask(text)
text = ""
}) {
Text("Add")
}
}
}
@Composable
fun TaskApp() {
val tasks = remember { mutableStateListOf(
Task(id = 0, text = "Task 1", done = false),
Task(id = 1, text = "Task 2", done = false),
Task(id = 2, text = "Task 3", done = false)
) }
fun handleAddTask(text: String) {
tasks.add(Task(nextId++, text, false))
}
fun handleChangeTask(task: Task) {
tasks.replaceAll { if (it.id == task.id) task else it }
}
fun handleDeleteTask(taskId: Int) {
tasks.removeIf { it.id == taskId }
}
Column {
Text(text = "Day off in Kyoto", style = MaterialTheme.typography.titleLarge)
AddTask(onAddTask = ::handleAddTask)
TaskList(tasks = tasks, onChangeTask = ::handleChangeTask, onDeleteTask = ::handleDeleteTask)
}
}
var nextId = 3
目前我遇到的问题是,用useReducer
val (tasks, dispatch) = useReducer<List<Task>, TaskAction>(
{ prevState, action ->
when (action) {
is TaskAction.Added -> prevState + Task(nextId++, action.text, false)
is TaskAction.Changed -> prevState.map { if (it.id == action.task.id) action.task else it }
is TaskAction.Deleted -> prevState.filter { it.id != action.taskId }
}
},
initialTasks
)
fun handleAddTask(text: String) {
dispatch(TaskAction.Added(text))
}
fun handleChangeTask(task: Task) {
dispatch(TaskAction.Changed(task))
}
fun handleDeleteTask(taskId: Int) {
dispatch(TaskAction.Deleted(taskId))
}
val initialTasks = listOf(
Task(id = 0, text = "Philosopher’s Path", done = true),
Task(id = 1, text = "Visit the temple", done = false),
Task(id = 2, text = "Drink matcha", done = false)
)
的时候不管我添加多少个task,列表里面只显示4个。。。