본문 바로가기
안드로이드 코틀린

[Kotlin][Android] Jetpack Compose 아이템 텍스트 수정하기

by teamnova 2024. 11. 15.
728x90

 

안녕하세요 오늘은 컴포즈로 만든 리스트에서 각 아이템의 텍스트를 수정을 해보겠습니다 

 

아이템마다 수정 버튼이 있습니다 

이때 TextField와 "확인" 및 "취소" 버튼이 나타나며, 사용자는 값을 수정할 수 있습니다.

 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
                                )
                            }

 

 

수정이 끝났을때 확인 버튼을 누르거나 수정한 내용을 취소하고자 할때 확인, 취소 버튼을 누릅니다. 

 

아래는 전체 코드입니다 

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
        )

        // 체크박스 리스트 표시
        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
                                )
                            }
                        }
                    }
                )
            }
        }
    }
}

 

 

시연 영상입니다