Group Study (2024-2025)/Android

[Android] 카카오뱅크 클론 코딩 (4)

c2c4 2024. 12. 18. 20:23

이번 주차에서 제가 맡았던 부분 중 '이체 화면 텍스트 필드' 에서 새롭게 알게 된 부분도 있고 어려웠던 부분도 한 번 더 자세히 알게 된 것 같아 해당 내용을 중심으로 정리해보겠습니다.

 

이체 화면 텍스트 필드

목표 : A 화면에서 사용자가 텍스트 필드에 입력한 값을 B 화면으로 넘어갈 때 매개변수로 담아서 보내주기

구현 방법 :

TransferScreen.kt (주요 코드 외 생략)

@Composable
fun TransferRoute(
    navigator: HomeNavigator
) {
    TransferScreen(
        onNextClick = { receiver ->
            navigator.navigateToSend(receiver) // receiver 값을 전달
        },
        onCloseClick = { navigator.navigateBack() }
    )
}

@Composable
fun TransferScreen(
    onNextClick: (String) -> Unit,
    onCloseClick: () -> Unit
) {
    var receiver by remember { mutableStateOf("") } // TextField 값 관리

    Column() {
        TransferTopBar(
            onTextChange = { receiver = it }, // 입력값 업데이트
            onCloseClick = onCloseClick
        )
        
        Box(
        ) {
            NextBox(
                text = "다음",
                receiver = receiver, // 현재 입력된 값을 전달
                onNextClick = { onNextClick(receiver) } // 버튼 클릭 시 현재 값 전달
            )
        }
    }
}

@Composable
fun TransferTopBar(
    onTextChange: (String) -> Unit,
    onCloseClick: () -> Unit
) {
    Column {
        Row(
            modifier = Modifier
                .fillMaxWidth()
                .padding(start = 15.dp),
            verticalAlignment = Alignment.CenterVertically,
        ) {
            SearchTextField(onTextChange = onTextChange) // 상태 변경 콜백 전달
        }
    }
}

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun SearchTextField(
    onTextChange: (String) -> Unit
) {
    var text by remember { mutableStateOf("") }

    OutlinedTextField(
        value = text,
        onValueChange = {
            text = it
            onTextChange(it) // 값이 변경되면 상위로 전달
        },
    )
}

위 코드에서 주요 흐름은 다음과 같습니다.

1. TransferRoute에서 HomeNavigator를 받아서 navigator에 저장한 후, TransferScreen을 호출하면서 onNextClick, onCloseClick에 navigator의 경로(즉, HomeNavigator의 경로)들을 담아서 보냅니다.

2. TransferScreen에서는 사용자가 텍스트 필드에 입력한 값을 receiver에 저장합니다.

  • TransferScreen에서 TransferTopBar 호출할 때 매개변수 onTextChange에 onTextChange = { receiver = it } 담아서 보냄
  • TransferTopBar 는 SearchTextField를 호출할 때 매개변수 onTextChange에 똑같이 onTextChange 담아서 보냄
  • SearchTextfield에서 텍스트필드를 생성할 때  onValueChange = { text = it     onTextChange(it)} 코드를 넣어서 생성
  • 즉, 텍스트필드에서 사용자가 값을 입력할 때마다 실시간으로 SearchTextfield -> TransferTopBar -> TransferScreen 으로 해당 내용이 전달되면서 receiver의 값이 업데이트 된다

3. 다음으로 넘어가는 버튼 (NextBox) 를 생성할 때 onNextClick 매개변수에 receiver값과 TransferScreen이 받은 onNextClick 경로를 담아서 보내줍니다. (NextBox 코드는 생략, 클릭 시 받은 경로대로 이동하도록 설정)

결론 : receiver 의 값을 잘 저장해뒀다가 '다음' 버튼을 눌렀을 때 navigator.navigateToSend(receiver) 를 호출한다!

 

HomeNavigator & HomeNavGraph (주요 코드 외 생략)

//HomeNavigator

class HomeNavigator(
    val navController: NavController
) {
    fun navigateToSend(receiver: String) {
        navController.navigate("send?receiver=$receiver")
    }
}


//HomeNavGraph

fun NavGraphBuilder.homeNavGraph(
    navigator: HomeNavigator
) {
    composable(
        route = "send?receiver={receiver}",
        arguments = listOf(navArgument("receiver") { type = NavType.StringType })
    ) { backStackEntry ->
        val receiver = backStackEntry.arguments?.getString("receiver") ?: "" // receiver 값 읽기
        SendRoute(navigator = navigator, receiver = receiver)
    }

}

1. HomeNavigator는 navigateToSend(receiver)를 호출받게 되면 receiver라는 값을 경로에 쿼리 파라미터로 포함시켜 send 화면으로 이동시킵니다.

2. 해당 route는 HomeNavGraph에 등록되어 있으며, route대로 오게 되면 receiver 값을 추출하여 SendRoute에 receiver 값을 매개변수로 담아 전달하게 됩니다.

결론 :  SendRoute는 HomeNavigator와 기타 매개변수를 받아서 꼭 필요한 것들만 담아 SendScreen을 호출해주는 용도로, 위 과정을 거치면 목표가 달성된다! 


이런 기능은 그 전에 구현해보지 못했던 기능이기도 하고 navigator와 navgraph에 대해 한 번 더 복습할 수 있어 좋았던 것 같습니다 :>