728x90
안녕하세요 오늘은 컴포즈로 구현한 아이템 리스트에서 선택된 아이템을 일괄적으로 삭제해보도록 하겠습니다
관련된 이전 포스팅은 아래에서 확인가능 합니다
목록이 간단할 때에는 큰 필요성을 느끼지 못할 수 있지만 아이템이 많아지면 많아질수록 대량의 아이템을 원하는대로 한번에 처리하는 기능은 꼭 필요한 기능 중 하나입니다
// 일괄 삭제 버튼
Row(modifier = Modifier.padding(16.dp)) {
Button(
onClick = {
// 선택된 아이템들 삭제
val iterator = items.iterator()
var index = 0
while (iterator.hasNext()) {
iterator.next()
if (selectedItems[index]) {
iterator.remove()
selectedItems.removeAt(index)
isEditing.removeAt(index)
index--
}
index++
}
},
enabled = selectedItems.contains(true) // 선택된 아이템이 있을 때만 활성화
) {
Text("선택된 아이템 전부 삭제")
}
}
먼저 삭제버튼을 만들어줍니다
선택된 아이템을 삭제할 때에는 반복문을 통해 item 리스트의 항목들을 순회하면서 선택된 아이템 (selectedItems), 즉 true 로 표시된 아이템들이 삭제됩니다.
아래는 전체 코드입니다
package com.example.kotlin_example
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Close
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.example.kotlin_example.ui.theme.Kotlin_exampleTheme
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
Kotlin_exampleTheme {
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background
) {
ItemList(cnt = 3)
}
}
}
}
}
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun ItemList(cnt: Int) {
// 아이템 리스트 초기화
val items = remember { mutableStateListOf<String>().apply { repeat(cnt) { add("Item ${it + 1}") } } }
// 체크 박스 상태 리스트
val selectedItems = remember { mutableStateListOf<Boolean>().apply { repeat(cnt) { add(false) } } }
// 편집 상태 리스트 (각 아이템이 수정 중인지 여부를 저장)
val isEditing = remember { mutableStateListOf<Boolean>().apply { repeat(cnt) { add(false) } } }
// 새로운 아이템 입력 상태
var newItemText by remember { mutableStateOf("") }
Column {
// 새로운 아이템 추가 입력 필드
Row(modifier = Modifier.padding(16.dp)) {
TextField(
value = newItemText,
onValueChange = { newItemText = it },
label = { Text("새 아이템 입력") },
modifier = Modifier.weight(1f)
)
Spacer(modifier = Modifier.width(8.dp))
Button(onClick = {
if (newItemText.isNotBlank()) {
items.add(newItemText)
selectedItems.add(false) // 새로운 아이템에 대해 체크박스 상태 추가
isEditing.add(false) // 새로운 아이템의 편집 상태 추가
newItemText = "" // 입력 필드 초기화
}
}) {
Text("추가")
}
}
// 선택된 아이템 개수를 표시
Text(
text = "선택된 아이템: ${selectedItems.count { it }}",
modifier = Modifier
.fillMaxWidth()
.padding(16.dp),
color = Color.Blue
)
// 일괄 삭제 버튼
Row(modifier = Modifier.padding(16.dp)) {
Button(
onClick = {
// 선택된 아이템들 삭제
val iterator = items.iterator()
var index = 0
while (iterator.hasNext()) {
iterator.next()
if (selectedItems[index]) {
iterator.remove()
selectedItems.removeAt(index)
isEditing.removeAt(index)
index--
}
index++
}
},
enabled = selectedItems.contains(true) // 선택된 아이템이 있을 때만 활성화
) {
Text("선택된 아이템 일괄 삭제")
}
}
// 체크박스 리스트 표시
LazyColumn {
itemsIndexed(items, key = { _, item -> item }) { index, item ->
val dismissState = rememberSwipeToDismissBoxState(
initialValue = SwipeToDismissBoxValue.Settled,
confirmValueChange = {
if (it != SwipeToDismissBoxValue.Settled) {
true
} else {
false
}
}
)
if (dismissState.currentValue != SwipeToDismissBoxValue.Settled) {
LaunchedEffect(dismissState.currentValue) {
if (dismissState.currentValue == SwipeToDismissBoxValue.EndToStart ||
dismissState.currentValue == SwipeToDismissBoxValue.StartToEnd) {
// 삭제할 때 리스트 인덱스가 변경되지 않도록 지연시키는 방식 사용
items.removeAt(index)
selectedItems.removeAt(index)
isEditing.removeAt(index)
}
}
}
SwipeToDismissBox(
state = dismissState,
backgroundContent = {
Box(
modifier = Modifier
.fillMaxSize()
.background(Color.LightGray)
.padding(16.dp)
)
// {
// Icon(
// imageVector = Icons.Default.Close,
// contentDescription = "삭제",
// tint = Color.Red
// )
// }
},
content = {
Row(
modifier = Modifier
.fillMaxWidth()
.padding(vertical = 8.dp)
.clickable {
selectedItems[index] = !selectedItems[index] // 체크박스 상태 토글
}
.padding(16.dp),
verticalAlignment = Alignment.CenterVertically
) {
Checkbox(
checked = selectedItems[index],
onCheckedChange = { checked -> selectedItems[index] = checked }
)
if (isEditing[index]) {
// 편집 모드일 때 TextField와 확인, 취소 버튼 표시
var editText by remember { mutableStateOf(item) }
TextField(
value = editText,
onValueChange = { newValue -> editText = newValue },
modifier = Modifier.weight(1f),
singleLine = true
)
Row {
// 확인 버튼
Button(onClick = {
items[index] = editText // 편집 후 값을 저장
isEditing[index] = false // 편집 모드 종료
}) {
Text("확인")
}
Spacer(modifier = Modifier.width(8.dp))
// 취소 버튼
Button(onClick = {
isEditing[index] = false // 편집 모드 종료
}) {
Text("취소")
}
}
} else {
// 기본 모드일 때 Text와 수정 버튼 표시
Text(
text = item,
color = Color.Black,
modifier = Modifier
.weight(1f)
.padding(start = 16.dp)
)
Spacer(modifier = Modifier.width(8.dp))
Button(onClick = {
isEditing[index] = true // 수정 버튼 클릭 시 편집 모드로 전환
}) {
Text("수정")
}
}
Spacer(modifier = Modifier.weight(1f)) // X 표시를 오른쪽으로 정렬하기 위한 spacer
// 기존 삭제 버튼 유지
IconButton(onClick = {
items.removeAt(index)
selectedItems.removeAt(index)
isEditing.removeAt(index)
}) {
Icon(
imageVector = Icons.Default.Close,
contentDescription = "삭제",
tint = Color.Red
)
}
}
}
)
}
}
}
}
@Preview(showBackground = true)
@Composable
fun GreetingPreview() {
Kotlin_exampleTheme {
ItemList(cnt = 100)
}
}
감사합니다
'안드로이드 코틀린' 카테고리의 다른 글
[Kotlin][Android] Jetpack Compose 텍스트 작성 중인 상태에 대해 사용자에게 알리기 (0) | 2024.11.27 |
---|---|
[Kotlin][Android] 문자열 형식 체크하기 (0) | 2024.11.23 |
[Kotlin][Android] Jetpack Compose 아이템 텍스트 수정하기 (0) | 2024.11.15 |
[Kotilin][Android] RatingBar을 사용해서 별점만들기 (2) | 2024.11.12 |
[Kotlin][Android] 디바이스 시간 여러 지역 시간으로 변경하기 (0) | 2024.11.11 |