[Android/Compose] 다이얼로그 구현

찌니·2022년 8월 11일
0

Android(Compose)

목록 보기
11/12
post-thumbnail

컴포즈를 사용하면서 느낀 점은 익숙해지는 과정은 세상 귀찮지만 꽤나 재밌고 간단하다는 점이다
다이얼로그도 그렇고 특히 리스트같은 간단해보이지만 속은 세상 귀찮은게 가득한 뷰들이 한껏 가벼워진다는 점

아래와 같은 다이얼로그의 경우에도 xml을 사용하면 어댑터을 사용해야하지만 컴포즈를 사용하면 세상 간단해진다

아래 코드를 보면서 세상 간단함을 함께 느껴봅시다
아직 코드 설명을 잘 못해서 이해하기 쉽지 않을 수 있음 주의 ㅜㅡㅜ!

MainActivity.kt


    // 다이얼로그의 상태 
    // 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)
                    }
                }
            }
        }
    }
}

DeclarationDialog.kt

@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)
                    )
                }
            }
        }
    }
profile
찌니's develog

2개의 댓글

comment-user-thumbnail
2023년 3월 9일

항상 잘 보고 갑니다. 선배님~👍🏻

1개의 답글