ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Android] Compose BasicTextField2를 써보자
    Android📱/삽질 기록... 2024. 9. 25. 23:46

    BasicTextField2를 써보자

     

    Compose에서 TextField를 사용할 때 

    커스텀을 많이하게 되는 거 같다

     

    그래서 일반 TextField 보다는 BasicTextField를 사용해서 dexorationBox의 인자로 텍스트 필드의 색상이나 

    기본 UI를 수정해야하는 일이 많다.

     

    그럴 때 쓰면 좋은 방식으로 BasicTextField2를 사용하는 걸 찾았는데

    아주 편리해서 공유한다

     

    기존 BasicTextField를 사용하면 2가지의 불편한 점이 존재했는데

     

    1. visualTransformation을 이용한 입력값 컨트롤

     

    이 부분은 장단점이 확실하다

    전화번호를 입력받아야 한다고 쳤을 때 

    000-0000-0000 이런식으로 입력을 받아야 한다면

    UX를 위해서 유저가 -을 직접 입력하는 거보다 자동으로 포매팅이 된다면 아주 편리할 것이다.

    그리고 만약 API 요청 시에도 -을 제거한 값을 보내야 한다면 visualTransformation을 적절하게 이용하면 아주 편리하다

    visualTransformation은 이름 그대로 실제 값은 01012345678이 상태 값으로 저장되지만 UI상에서는 010-1234-5678로 되게 나오는 방식이다.

     

    그렇다 보니 단점은 input 값을 컨트롤하기가 까다롭다 index 값을 계산해서 visualTransformation이 되기 전의 인덱스와 후의 인덱스를 분기를 쳐주는 로직이 필요하기 때문이다.

     

    VisualTransformation을 상속받은 class를 구현해서 처리를 해줘야 해서 장단점이 명확하다.

     

    2. DecorationBox의 너무 많은 인자

     

    텍스트 필드를 커스텀할 때 DecorationBox를 이용해서 필요 없는 인자들 까지 전달해야 한다

     

    TextField 컴포져블을 보면 상당히 많은 값을 가지고 있는데

    이 설정들이 DecorationBox를 위한 설정이 많다.

     

    물론 저 옵션들을 사용해야 한다면 굉장히 편리하겠지만

    다 쓰는 게 아니고 커스텀을 해야 한다면 코드 작성 시 불필요한 인자들일뿐이라고 생각한다.

     

    BasicTextField2!!

     

    위 문제들을 BasicTextField2를 사용하면 해결이 가능하다.

     

    1번의 단점 같은 경우 BasicTextField2는 inputTransformation이라는 람다를 통해서 input 값을 간단하게 조작이 가능해서

    포매팅을 추가하거나 입력한 값을 조정하는 게 편하게 컨트롤이 가능하다.

     

    다만, VisualTransformation과는 다르게 직접 input 값을 바꾸는 방식이기 때문에 만약

     

    "-을 보이게는 하고 싶지만 서버에는 숫자만 보낼 거야!"

    "1,000원으로 보이게 할 거지만 실제 값은 1000이면 좋겠어"

     

    같은 상황이라면 값을 다시 정리를 해주어야 한다.

     

    개인적으로 2번이 편했는데

    BasicTextField2는 UI 커스텀을 할 때 decorator에 직접 컴포져블을 작성해서 UI를 커스텀할 수 있기 때문에 DecorationBox에 인자를 넘겨주어야 하는 작업이 줄어든다.

     

    예시)

    BasicTextField2(
        modifier = Modifier.fillMaxWidth(),
        value = value,
        onValueChange = onValueChange,
        textStyle = TextStyle(
            fontWeight = FontWeight.Medium,
            fontSize = 18.sp,
            color = SwingColorSystem.Primary
        ),
        keyboardOptions = keyboardOptions,
        keyboardActions = keyboardActions,
        inputTransformation = inputTransformation,
        readOnly = readOnly,
        lineLimits = TextFieldLineLimits.SingleLine,
        decorator = { innerTextField ->
            Column(
                modifier = Modifier
            ) {
                Box(
                    modifier = Modifier
                        .fillMaxWidth()
                        .padding(vertical = 10.dp)
                ) {
                    
                    innerTextField()
    
                }
    
                HorizontalDivider(
                    modifier = Modifier,
                    color = SwingColorSystem.G200,
                    thickness = 2.dp
                )
    
             
            }
        }
    )

     

    주의 사항

     

    BasicTextField2의 또 다른 차이점은 state값을 보여주지 않는다는 것이다.

     

    보통 Compose에서 TextField를 remember의 예시로 많이 사용한다

    이유는 remember와 State를 사용하지 않으면 TextField의 값을 바꾸는 걸 할 수 없기 때문이다. (Recomposition 관련)

    하지만 BasicTextField2는 내부에서 value를 copy 해서 값을 들고 있기 때문에 값을 받을 수는 없지만 입력은 된다.

     

    이게 무슨 문제가 있냐면 글자 수를 제한하고 싶거나, 특정 문자의 입력을 막고 싶을 때 

    단순히 onValueChange에서 값을 컨트롤하려고 하면

    일단 입력이 된 다음 포커스가 사라지면 내가 원하는 값으로 입력값이 바뀌는 현상이 일어나게 된다.

     

    이 문제를 해결하기 위해서는 inputTransformation을 이용해서 값을 조정해 주는 게 좋다

Designed by Tistory.