본문 바로가기

Android/Senty

[Senty] xml 기반의 view에서 Compose로 100% 모든 뷰를 변경

안드로이드 앱 개발을 학습한 이후로, 가장 처음 배포했던 나의 앱 Senty를 리팩토링했다.

넣고 싶었던 기능을 더 추가로 넣어주었고, 그 사이에 더 학습한 내용들도 적용해주었다.

새삼 .. 이런 것도 할 줄 알게되었구나 느낄 수 있었던 시간 .. (코쓱

 

 

가장 하고싶었던 것은 사실 Compose를 적용하는 일이었다!


Compose로 변경한 이유?

Compose를 처음 알게된 것은 GDSC에서였고, 그때 얼레벌레 사용해보면서 호기심을 자극했었다.

상태를 관리하는 것 때문인지 러닝커브가 높다는 평이 있었고, 그래서 더욱 내 프로젝트에 적용해보고싶었다.

가장 최근에 진행한 랜덤리즘은 왜 컴포즈를 사용하지 않았냐고 묻는다면, 빠르게 결과물을 내고 싶었기 때문이었다.

컴포즈는 익숙하지 않았고 그렇기에 xml으로 레이아웃을 작성하는 것이 나에게는 더 빠르게 결과물을 낼 수 있었다.

그런데 이번에 하나하나 변경하고, 적용해보면서 컴포즈도 편하다..! 좋다!!! 라는 것을 체험했다.

 

 

현재 모든 xml 파일을 삭제하고 layout 폴더에는 하나도 남아있지 않다! (야호)

 

 

Compose를 적용하면서 어려웠던 점

1️⃣  자주 사용되는 컴포넌트를 공통 컴포넌트로 만드는 것

데이터를 입력하는 부분에는 위와 같은 형태로 되어있다.

제목이 있고, 그 아래에 TextField가 위치한 ....!! 형태

그래서 이 부분을 여러 곳에서 사용할 수 있도록 따로 빼내어 작성을 해보았는데, 생각보다 쉽지 않았다.

고려해야 하는 부분이 있었지만 난 그것을 몰랐다.

 

@Composable
fun SentyTextField(
    modifier: Modifier = Modifier,
    text: String,
    hint: String,
    hintSize: TextUnit = TextUnit.Unspecified,
    isError: Boolean = false,
    errorMsg: String,
    enabled: Boolean = true,
    inputType: KeyboardType = KeyboardType.Text,
    onChangeText: (String) -> Unit,
) {
    TextField(
        keyboardOptions = KeyboardOptions(
            keyboardType = inputType
        ),
        modifier = modifier,
        value = text,
        onValueChange = {
            onChangeText(it)
        },
        placeholder = {
            Text(text = hint, fontSize = hintSize)
        },
        colors = TextFieldDefaults.colors(
            focusedContainerColor = Color.White,
            unfocusedContainerColor = Color.White,
            unfocusedIndicatorColor = Green40,
            focusedIndicatorColor = Green40,
            disabledContainerColor = Color.White,
            disabledIndicatorColor = Green40,
            disabledPlaceholderColor = Color.Unspecified,
            errorContainerColor = Color.White,
            cursorColor = Green40,
        ),
        singleLine = true,
        maxLines = 1,
        isError = isError,
        readOnly = !enabled,
        supportingText = {
            if (isError) {
                Text(text = errorMsg)
            }
        },
    )
}

 

함수명은 BasicTextField를 뜻하는 이름에서 앱이름+TextField로 작성해주었다.

 

 

프리뷰로 보면 위와 같다!

처음에는 이렇게 형태를 만들어놓고 쭉 사용을 해왔는데, 한 가지 문제가 발생한 부분은 다음과 같았다.

 

 

이 부분은 데이터를 입력하는 부분이 아닌, 조회하는 화면이다.

 

똑같은 포맷을 가지고 있지만, 다른 점이 존재했다.

1. 밑줄의 색이 다르다는 점 

-> readOnly를 통해 컨트롤

2. placeholer가 아닌 text가 보여져야 한다는 점

-> placeholder에도 보여져야 하는 text값으로 세팅

3. 클릭이 되지 않아야 한다는 점 (데이터를 입력하기 위한 클릭X)

-> 분기처리를 하고 readOnly 로 설정

 

추가되어지는 부분들이 많아지다보니 해당 컴포저블 함수를 커스터마이징하려면 기본적으로 가지고 있는 매개변수들을 모두 똑같이 지니고 있어야 하겠구나를 깨닳았다.

아직 나는 다른 부분들을 완성해야하느라 당장 필요한 부분만 추가하고 전체적으로는 수정하지 않았지만 마음먹고! 날 잡고 수정해야될 것 같기는 하다.

 

2️⃣  상태를 관리하는 것

가장 어려웠던 부분 ..

내가 예상했던 대로 되지 않아서 어려웠다.

 

그래도 이 전에 원티드 프리온보딩을 통해 컴포즈에 대한 내용을 들었었는데, 그때의 학습자료도 참고하여 컴포즈의 작동 방식에 대해 일단 가장 먼저 복습했다. 트리 형식으로 리컴포지션이 발생하면 누구에게 영향을 미치는지!

그리고 상태 호이스팅에 대해 공식문서를 읽어보았다!! 

 

상태 및 Jetpack Compose  |  Android Developers

이 페이지는 Cloud Translation API를 통해 번역되었습니다. 상태 및 Jetpack Compose 컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요. 앱의 상태는 시간이 지남에 따라

developer.android.com

 

읽으면서 remember/rememberSaveable에 key값을 왜 지정해주는지에 대해 알게되었고, 적용해볼 수 있었다!

 


컴포즈로 변경하면서 좋았던 점

1) 기존에는 xml <-> kotlin 을 전환해가며 코드를 작성했다면, 그냥 kotlin 하나로 모든 것을 해결할 수 있었다는 점

2) 리스트를 만들어야 한다면 holder, adapter를 작성해주었었는데 따로 추가적으로 생성할 필요없이 LazyColumn이나 Row를 사용하면 된다는 점

3) 데이터를 넣어서 다양한 UI 테스트를 해볼 수 있다는 점

 

위의 3개가 가장 좋았다!

 


좋지 않았던 점

좋지 않았던 점은 딱히 없었다 .. 상태를 어떻게 다루어야 할지 고민이 된다는 점?

 


마무리

컴포즈를 사용함에 있어 이제는 머뭇거리지 않게 되었다!

새로운 프로젝트를 시작하게되는데, 컴포즈를 사용하겠다고 자신있게 얘기했다!

이제 뷰를 그리는 방법에 있어서 2가지를 모두 사용할 수 있게 되었다!

 

PlayStore

 

Senty - 선물 기록 어플리케이션 - Google Play 앱

소중한 사람들과 정성스레 주고받은 선물을 기록해보세요.

play.google.com