가계부앱을 개발하다가 돈을 입력하는 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 입력 변화 이베늩 처리