profile image

L o a d i n g . . .

반응형

 

Compose에서는 EditText가 TextField로 되어 있고, 이를 커스텀 하기 위해서는 BasicTextField을 사용해야 한다는 것을 알았다.

 

1. 문제발생

내가 원하는 TextField는 위 이미지와 같이 되어 있으며 양 끝에는 Icon Vector 이미지가 들어가게 하고 싶었다.

네이티브라면 바로 해버렸을 이 디자인을 꽤 오랜시간 만지게 되었다.

BasicTextField(
    modifier = Modifier.wrapContentWidth(),
    textStyle = TextStyle(textAlign = TextAlign.Start),
    value = priceTextValue,
    maxLines = 1,
    keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),
    singleLine = true,
    onValueChange = { priceTextValue = it },
    visualTransformation = VisualTransformation.None,
    decorationBox = { innerTextField ->
        Row(
            modifier = Modifier
                .fillMaxWidth()
                .border(
                    width = 1.dp,
                    color = Color.Black,
                    shape = RoundedCornerShape(size = 16.dp)
                )
                .padding(all = 16.dp),
            verticalAlignment = Alignment.CenterVertically,
        ) {
            Icon(
                imageVector = Icons.Default.Check,
                contentDescription = "",
                tint = Color.Black,
            )
            Spacer(
                modifier = Modifier.width(width = 8.dp)
            )
            Box(
                modifier = Modifier.weight(1f)
            ) {
                innerTextField()
            }
            Spacer(
                modifier = Modifier.width(width = 8.dp)
            )
            Icon(
                imageVector = Icons.Default.Clear,
                contentDescription = "",
                tint = Color.Black,
            )
        }
    },
)

 

구글링을 가지고 내가 커스텀한 코드이기는 하고 상당히 당황스러운 부분이 많이 있었다.

정말 네이티브보다 Compose가 더 좋고 커스텀하기 편한건지 또 다시 의문이 들기 시작하기도 했다.

 

2. 둥근 라운드 만들기

일단 둥근 라운드를 만들어야 하는 문제부터 해결해야 했고 decorationBox 에서 구현이 가능하다는 정보를 찾을 수 있었다.

Row에서 modifer을 가지고 border을 건드리면 라운드를 손쉽게 만들 수 있었다.

modifier = Modifier
                .fillMaxWidth()
                .border(
                    width = 1.dp,
                    color = Color.Black,
                    shape = RoundedCornerShape(size = 16.dp)
                )

 

3. 양 끝에 Icon 삽입

위에서 Row를 구현했으므로 icon들은 순서대로 넣으면 되었다.

하지만 마지막 Icon(close 모양)을 끝에 보내기란 지금 나에겐 너무 힘든 일이었다.. 네이티브였다면 그냥...아오

좀 들여다보니 innerTextField()의 사이즈가 조절이 안되었다.. 안에 텍스트가 많아지면 자동으로 width가 늘어나기는 했지만 아무것도 입력이 안된 상태에서도 어느정도의 최소 width를 먹고 있어서 Icon이 끝이 아닌 어중간한 위치해 있게 되었다.

 

그렇다고 innerTextField를 커스텀할 수 있지는 않아보였고 결국에는 Box를 하나 씌우게 되었다.

 Box(
                modifier = Modifier.weight(1f)
            ) {
                innerTextField()
            }

 

처음에는 MaxWidth을 하면 나머지 공간을 모두 차지할 줄 알았는데. 나머지가 아닌 모든 공간을 차지해버리는 현상이 나와서 또 찾아보다가 weight를 1f로 주게되면 나머지 공간만 차지하게 된다는 정보를 찾을 수 있었다.

결과적으로 위와 같은 이미지처럼 구현할 수 있었다.

 

3. InputType는 어디에?

TextField를 사용하게 되면서 InputType은

keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number)

keyboardOptions로 바뀌게 되었다. 

companion object {
        /**
         * A keyboard type used to request an IME that shows regular keyboard.
         */
        @Stable
        val Text: KeyboardType = KeyboardType(1)

        /**
         * A keyboard type used to request an IME that is capable of inputting ASCII characters.
         */
        @Stable
        val Ascii: KeyboardType = KeyboardType(2)

        /**
         * A keyboard type used to request an IME that is capable of inputting digits. IME may
         * provide inputs other than digits but it is not guaranteed.
         *
         * @see KeyboardType.Decimal
         */
        @Stable
        val Number: KeyboardType = KeyboardType(3)

        /**
         * A keyboard type used to request an IME that is capable of inputting phone numbers.
         */
        @Stable
        val Phone: KeyboardType = KeyboardType(4)

        /**
         * A keyboard type used to request an IME that is capable of inputting URIs.
         */
        @Stable
        val Uri: KeyboardType = KeyboardType(5)

        /**
         * A keyboard type used to request an IME that is capable of inputting email addresses.
         */
        @Stable
        val Email: KeyboardType = KeyboardType(6)

        /**
         * A keyboard type used to request an IME that is capable of inputting password.
         */
        @Stable
        val Password: KeyboardType = KeyboardType(7)

        /**
         * A keyboard type used to request an IME that is capable of inputting number password.
         */
        @Stable
        val NumberPassword: KeyboardType = KeyboardType(8)

        /**
         * A keyboard type used to request an IME that is capable of inputting decimals.
         * IME should explicitly provide a decimal separator as input, which is not assured by
         * [KeyboardType.Number].
         */
        @Stable
        val Decimal: KeyboardType = KeyboardType(9)
    }

keyboardOptions에 기존에 InputType들이 들어있다. 혹시라도 괜히 구현할 생각은 하지말자

반응형
복사했습니다!