ToDoリストの各項目に削除ボタンを付ける

実装するために、以下のことを行います。
- TodoListScreen 内で、ToDoリストの各項目 (Card の中) に削除ボタンを追加する。
- 削除ボタンが押されたときに、対応する項目をリストから削除するロジックを実装する。
具体的な手順
MainActivity.kt ファイルの TodoListScreen 関数を編集していきます。
1. 必要なimportを追加
ファイルの先頭あたりに、以下を追加してください。(既にあるものもあるかもしれません)
import androidx.compose.foundation.clickable // 項目全体をクリック可能にする場合
import androidx.compose.material.icons.Icons // アイコン用
import androidx.compose.material.icons.filled.Delete // 削除アイコン用
import androidx.compose.material3.Icon // アイコン表示用
import androidx.compose.material3.IconButton // クリック可能なアイコンボタン用
import androidx.compose.foundation.layout.Arrangement // 配置用
2. TodoListScreen を修正して削除ボタンを追加する
TodoListScreen 関数の中の LazyColumn の items ブロックを以下のように変更します。
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun TodoListScreen(navController: NavController) {
var todoItems by rememberSaveable { mutableStateOf(mutableListOf<String>()) }
var newTodoText by rememberSaveable(stateSaver = TextFieldValue.Saver) {
mutableStateOf(TextFieldValue(""))
}
Column(
modifier = Modifier.fillMaxSize().padding(16.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(
text = "ToDoリスト",
fontSize = 24.sp,
modifier = Modifier.padding(bottom = 16.dp)
)
OutlinedTextField(
value = newTodoText,
onValueChange = { newValue -> newTodoText = newValue },
label = { Text("新しいToDo") },
singleLine = true,
modifier = Modifier
.fillMaxWidth()
.padding(bottom = 8.dp)
)
Button(
onClick = {
if (newTodoText.text.isNotBlank()) {
// immutableなListに追加し、新しいリストを代入
todoItems = (todoItems + newTodoText.text).toMutableList()
newTodoText = TextFieldValue("")
}
},
modifier = Modifier.fillMaxWidth().padding(bottom = 16.dp)
) {
Text("追加")
}
// ToDoリストを表示するLazyColumn
LazyColumn(
modifier = Modifier.fillMaxSize()
) {
items(todoItems) { item ->
Card(
modifier = Modifier
.fillMaxWidth()
.padding(vertical = 4.dp),
border = BorderStroke(1.dp, Color.LightGray)
) {
// Rowを使ってテキストと削除ボタンを横に並べる
Row(
modifier = Modifier.fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceBetween // テキストとボタンを両端に配置
) {
Text(
text = item,
modifier = Modifier
.weight(1f) // テキストが利用可能なスペースを埋めるようにする
.padding(start = 16.dp, end = 8.dp) // 左右のパディング
)
IconButton(onClick = {
// 削除ボタンが押されたときの処理
// 現在のアイテムをリストから除外して、新しいリストを代入する
todoItems = todoItems.filter { it != item }.toMutableList()
}) {
Icon(Icons.Filled.Delete, contentDescription = "削除")
}
}
}
}
}
Button(
onClick = { navController.popBackStack() },
modifier = Modifier.padding(top = 16.dp)
) {
Text("戻る")
}
}
}
- Row: Text と IconButton を横方向に並べるために使用します。
- horizontalArrangement = Arrangement.SpaceBetween: Row 内の要素を両端に配置し、間にスペースを空けます。
- Text(…, modifier = Modifier.weight(1f)): Text が利用可能な横幅いっぱいに広がり、削除ボタンのスペースを確保します。
- IconButton(onClick = { … }): クリック可能なアイコンボタンです。
- Icon(Icons.Filled.Delete, contentDescription = “削除”): Material Designの削除アイコンを表示します。contentDescription はアクセシビリティのために重要です。
- todoItems = todoItems.filter { it != item }.toMutableList(): ここが削除のロジックです。filter 関数を使って、現在選択された item 以外のすべての項目で新しいリストを作成し、それを todoItems に再代入しています。これでUIが自動的に更新され、削除された項目が表示されなくなります。
これで、ToDoリストの各項目に削除ボタンが表示され、そのボタンを押すとリストから項目が削除されるようになります。
※Google AI Studioによる回答を参考にしました
