Formatting number with currency symbol and thousand separators is quite common, and it's tricky to implement it. Popular answer on StackOverlow with pure TextWatcher isn't really satisfactory and has many potential side-effects.
Android provides more than 20 span types and Span is a way to change the rendering for the text without touching the text. i.e. Span implementation changes the UI NOT data.
// Add the watcher that inserts monetary span to your TextView.
val watcher = MonetaryCharWatcherImpl(locale, currencyCode)
textView.addTextChangedListener(watcher)
// Remove the watcher.
textView.removeTextChangedListener(watcher)
I'm a big fan of Reactive pattern so I also implement a rx-wrapper for automatic disposing.
MonetaryTextWatcher
.applyTextView(
textView = binding.monetaryTextInput,
locale = Locale.getDefault(),
currencyCode = "USD", // or JPY
isAnnotatingCharByChar = true
)
.subscribe()
.addTo(disposables)
This is a demo project for a talk in Android Taipei meetup. The original slide is here.