컴포즈를 사용하면서 느낀 점은 익숙해지는 과정은 세상 귀찮지만 꽤나 재밌고 간단하다는 점이다
다이얼로그도 그렇고 특히 리스트같은 간단해보이지만 속은 세상 귀찮은게 가득한 뷰들이 한껏 가벼워진다는 점
아래와 같은 다이얼로그의 경우에도 xml을 사용하면 어댑터을 사용해야하지만 컴포즈를 사용하면 세상 간단해진다
아래 코드를 보면서 세상 간단함을 함께 느껴봅시다
아직 코드 설명을 잘 못해서 이해하기 쉽지 않을 수 있음 주의 ㅜㅡㅜ!
// 다이얼로그의 상태
// false -> 숨김, true -> 뷰 노출
var declarationDialogState by remember {
mutableStateOf(false)
}
Scaffold(
scaffoldState = scaffoldState,
topBar = {
TopAppBar(
title = {},
// action 아이콘 클릭시 다이얼로그 상태를 true 로 만들어주며 노출
actions = {
IconButton(onClick = { declarationDialogState = true }) {
Icon(Icons.Filled.Warning, contentDescription = "", tint = Color.Red)
}
},
navigationIcon = {
IconButton(onClick = { navHostController.navigateUp() }) {
Icon(Icons.Filled.ArrowBack, contentDescription = "")
}
},
backgroundColor = Color.Transparent,
elevation = 0.dp
)
}
) {
Surface(modifier = Modifier
.padding(it)
.fillMaxSize()) {
// 다이얼로그 표시
if (declarationDialogState) {
DeclarationDialog(type = 1) // 다이얼로그 컴포즈
{ declarationDialogState = false } // 다이얼로그를 숨기는 unit 함수를 인자로 줌
}
Column {
Text(text = "상품 자세히 보기", fontSize = 20.sp, modifier = Modifier.padding(start = 30.dp, top = 10.dp, bottom = 20.dp))
Row() {
Spacer(modifier = Modifier.width(30.dp))
val modifier = Modifier.size(150.dp)
post.productImg?.let {
ItemImage(productImg = post.productImg, modifier = modifier)
}
Spacer(modifier = Modifier.width(30.dp))
Text(text = post.title, fontSize = 20.sp)
}
Spacer(modifier = Modifier.height(30.dp))
Surface(shape = MaterialTheme.shapes.large.copy(topEnd = CornerSize(70.dp))) {
Column(modifier = Modifier
.fillMaxSize()
.background(color = Color(0xff00ac77))) {
Text(text = "내 위치에서 ${post.distance}km", fontSize = 20.sp, color = Color.White)
Text(text = "$validateType : $day", fontSize = 20.sp, color = Color.White)
}
}
}
}
}
}
@Composable
fun DeclarationDialog(onChangeState: () -> Unit) {
val declarations = listOf("부적절한 언어 사용(욕설, 비속어)", "불쾌함 유발", "어쨋든 잘못함", "기타")
AlertDialog(
// 다이얼로그 뷰 밖의 화면 클릭시, 인자로 받은 함수 실행하며 다이얼로그 상태 변경
onDismissRequest = { onChangeState() },
title = { Text(text = "신고", modifier = Modifier.fillMaxWidth(), textAlign = TextAlign.Center) },
text = {
Column {
Text(text = "신고 사유", modifier = Modifier.padding(bottom = 5.dp))
RadioButtons(declarations)
}
},
dismissButton = {
// 취소 버튼 클릭시 인자로 받은 함수 실행하며 다이얼로그 상태 변경
TextButton(onClick = { onChangeState() }) {
Text(text = "취소", color = Color.Black)
}
},
confirmButton = {
// 신고 버튼 클릭시 인자로 받은 함수 실행하며 다이얼로그 상태 변경
TextButton(
onClick = {
// 원하는 실행문 작성
onChangeState()
}) {
Text(text = "신고", color = Color.Black)
}
}
)
}
// 다이얼로그에 들어가는 라디오버튼
@Composable
fun RadioButtons(declaration: List<String>){
val selectedValue = remember { mutableStateOf("") } // 선택된 라디오 버튼에 해당하는 내용
val isSelectedItem: (String) -> Boolean = {selectedValue.value == it}
val onChangeState : (String) -> Unit = { selectedValue.value = it}
Column(modifier = Modifier.padding(top = 10.dp)) {
declaration.forEach { item ->
Column {
Row (
modifier = Modifier
.selectable( // 선택 가능한 상태
// selectedValue가 해당 item 과 같을때 선택된 상태를 의미
selected = isSelectedItem(item),
// 해당 라인 클릭시 selectedValue 값을 변경해 상태 변경
onClick = { onChangeState(item) },
role = Role.RadioButton
)
.padding(bottom = 3.dp)
){
RadioButton(
// 선택됨을 나타내는 인수와 같음
// selectedValue가 해당 item 과 같을때 선택됨 표시
selected = isSelectedItem(item),// 선택됨을 나타내는 인수와 같음
onClick = null,
modifier = Modifier.padding(end = 5.dp)
)
Text(text = item)
}
// 기타 버튼 선택시 작성할 수 있는 TextField 노출
if (selectedValue.value == "기타" && item == "기타"){
TextField(
value = selectedValue.value,
onValueChange = {selectedValue.value = it},
modifier = Modifier.height(30.dp)
)
}
}
}
}
항상 잘 보고 갑니다. 선배님~👍🏻