가계부앱을 개발하다가 돈을 입력하는 EditText에서 화폐 단위를 표시해주면 좋겠다해서 관련된 글을 찾아보다가 좋은 글이 있어서 정리하게 되었습니다.

<EditText
android:id="@+id/krw_edit_view"
android:layout_width="0dp"
android:layout_height="0dp"
android:gravity="end"
android:inputType="number"
android:textSize="35sp"
app:layout_constraintBottom_toBottomOf="@id/krw_label"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/krw_label"
app:layout_constraintTop_toTopOf="@id/krw_label" />
우선 XML의 소스 코드입니다.
EditText를 선언하였고 금액(숫자)만 입력받기 위해서 inputType 속성으로 "number"를 지정하였습니다.
EditText의 입력을 오른쪽부터 받기 위해서 gravity 속성은 "end"로 지정하였습니다.
화폐 단위를 표시하기 위해서 DecimalFormat과 TextWathcer를 사용합니다.
private val decimalFormat = DecimalFormat("#,###")
private var result: String = ""
DecimalFormat을 선언하는데, DecimalFormat은 10진수의 숫자를 포맷하는 클래스입니다. 이 클래스의 생성자로 "#,###"을 지정하여 원화 단위(네 글자가 되면 쉼표 추가)로 텍스트를 바꿔줍니다. 사용할 수 있는 포맷 패턴이 여러가지 존재하는데 자세한 내용은 링크에 나와있습니다.
private val watcher = object : TextWatcher {
override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
}
override fun onTextChanged(charSequence: CharSequence?, p1: Int, p2: Int, p3: Int) {
if(!TextUtils.isEmpty(charSequence.toString()) && charSequence.toString() != result){
result = decimalFormat.format(charSequence.toString().replace(",","").toDouble())
binding.krwEditView.setText(result);
binding.krwEditView.setSelection(result.length);
}
}
override fun afterTextChanged(p0: Editable?) {
}
}

다음 단계로 TextWatcher 인터페이스를 구현하는 객체를 선언합니다. TextWatcher 인터페이스는 Editable한 뷰에 붙으면 텍스트가 변경될 때 메소드를 호출할 수 있습니다. Editable한 뷰의 대표적인 예로는 EditText가 있으며 인터페이스의 메소드는 아래와 같습니다.
beforeTextChanged(CharSequence, int, int, int)
입력하여 변화가 생기기 전에 처리는 이 메소드를 구현합니다.
onTextChanged(CharSequence, int, int, int)
변화와 동시에 처리를 해주고자 할 때는 이 메소드를 구현합니다.
afterTextChanged(Editable)
입력이 끝났을 때 처리는 이 메소드를 구현합니다.
위의 코드에서는 onTextChanged 메소드를 오버라이드하여 텍스트가 변하면 바로 호출되도록 구현하였습니다. 우선 if문에서 !TextUtils.isEmpty(charSequence.toString())을 통해 EditText가 비어있지 않을 때만 실행하도록 작성합니다.
그리고 그 다음 조건인 charSequence.toString() != result 부분은 TextWatcher는 계속해서 EditText를 검사하게 되는데 그 때마다 이 메소드를 반복 실행합니다. 따라서 변경된 부분이 없는데 반복적으로 포맷을 변경하고 EditText의 text를 지정하는 것은 불필요한 동작이기에 이 전의 결과값과 동일하면 실행시키지 않고, 동일하지 않으면 실행시키는 구문을 작성하였습니다.
binding.krwEditView.addTextChangedListener(watcher)
마지막으로 EditText의 addTextChangedListener를 사용하여 리스너를 설정하면 됩니다.
참조
EditText 화폐 단위 표시
자바 숫자 Format 변경 - DecimalFormat
안드로이드 EditText 입력 변화 이베늩 처리