본문 바로가기

Android

[Android] EditText에서 숫자 입력 시 1000단위 Comma(',')로 구분하여 보여주기 (Kotlin)

개요

안드로이드 개발을 하며 EditText 사용 시 숫자만 입력받는 경우가 있다. 특히 금액에 관련된 입력을 받을 때에는 숫자가 커질수록 3자리 기준 Comma(',')로 나누지 않는다면 사용자가 금액을 읽기에 불편함이 있을 것이다.

이 문제를 해결하기 위해 사용자가 금액을 입력하거나 삭제할때마다 콤마가 포함되어 보이는 기능을 구현하였다.

Kotlin으로 작성했고 여러곳에서 사용할 수 있도록 EditText의 확장 함수로 구현하였다.

1. EditText 정의하기

금액를 입력받기 위한 EditText를 정의하고 숫자만 나오는 키패드를 띄우기 위해 inputType을 number로 지정한다.

금액의 최댓값을 100억으로 설정하기 위해 maxLength는 14로 정의하였다. (숫자와 콤마 포함 길이 / 10,000,000,000)

// fragment_number_comma.xml
<EditText
    android:id="@+id/editText_amount"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:inputType="number"
    android:maxLength="14" />

 

2. TextWatcher를 정의하여 EditText의 리스너로 등록하기

숫자를 입력받을 때마다 1000 단위로 숫자와 Comma를 함께 보여주기 위한 TextWatcher를 정의한다.

beforeTextChanged() 메서드를 통해 기존 텍스트의 길이와 커서의 위치를 기억하고,

afterTextChanged() 메서드에서는 텍스트가 입력인지 삭제인지 확인하여 숫자를 콤마 포맷으로 변환하고 알맞은 위치에 커서를 세팅하였다.

(해당 기능은 여러 곳에서 사용할 수 있도록 EditText의 확장 함수로 구현하였다.)

// ViewUtils.kt
const val MAX_NUMBER_AMOUNT_LENGTH = 14

fun EditText.addNumberCommaFormatTextWatcher() {
    addTextChangedListener(object : TextWatcher {
        var beforeIndex = 0
        var beforeLength = 0

        override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
            beforeIndex = start
            beforeLength = s?.length ?: 0
        }

        override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {}

        override fun afterTextChanged(e: Editable) {
            removeTextChangedListener(this)

            val currentLength = text.toString().length

            if (currentLength <= MAX_NUMBER_AMOUNT_LENGTH) {

                convertNumberToCommaFormat()

                val selectionIndex =
                    if (beforeLength < currentLength) {
                        when {
                            beforeIndex == beforeLength -> currentLength
                            beforeLength + 2 == currentLength -> beforeIndex + 2
                            else -> beforeIndex + 1
                        }
                    } else {
                        when {
                            beforeIndex == beforeLength - 1 -> currentLength
                            beforeLength - 2 == currentLength -> beforeIndex - 1
                            else -> beforeIndex
                        }
                    }

                try {
                    setSelection(selectionIndex)
                } catch (e: Exception) { }

                addTextChangedListener(this)
            }
        }

        fun convertNumberToCommaFormat() = run {
            val numberText = text.toString()
            val decimalFormat = DecimalFormat("#,###")

            if (!TextUtils.isEmpty(numberText)) {
                val number = numberText.replace(",".toRegex(), "").toDouble()

                setText(decimalFormat.format(number))
            }
        }
    })
}

 

3. 숫자를 입력받는 화면(Activity, Fragment)에서 구현한 확장 함수를 EditText에 적용한다.

// NumberCommaFragment.kt
override fun onCreateView(
    inflater: LayoutInflater, container: ViewGroup?,
    savedInstanceState: Bundle?
): View {
    val binding = FragmentNumberCommaBinding.inflate(inflater, container, false)
        .apply {

            editTextAmount.addNumberCommaFormatTextWatcher()
        }
    return binding.root
}

참고