Skip to content

Instantly share code, notes, and snippets.

@Gnzlt
Last active January 4, 2019 10:15
Show Gist options
  • Select an option

  • Save Gnzlt/3e10077bdfb82e87c7866c1dc61aa197 to your computer and use it in GitHub Desktop.

Select an option

Save Gnzlt/3e10077bdfb82e87c7866c1dc61aa197 to your computer and use it in GitHub Desktop.
Android TextView formatted to show Currency values from a Float
package com.example
import android.content.Context
import android.support.v7.widget.AppCompatTextView
import android.util.AttributeSet
import java.text.DecimalFormat
import java.util.Currency
class PriceTextView(context: Context, attrs: AttributeSet?) : AppCompatTextView(context, attrs) {
companion object {
private const val DEFAULT_PRICE = "0"
}
private val currencyFormatter = DecimalFormat.getCurrencyInstance() as DecimalFormat
private var maximumIntegerDigits = currencyFormatter.maximumIntegerDigits
private var maximumFractionDigits = currencyFormatter.maximumFractionDigits
private var decimalSeparator = currencyFormatter.decimalFormatSymbols.decimalSeparator
private var valueListener: ((Double) -> Unit)? = null
private var errorListener: (() -> Unit)? = null
private var currentPrice = DEFAULT_PRICE
override fun onFinishInflate() {
super.onFinishInflate()
updatePrice()
}
fun addNumber(number: Int) {
if (currentPrice != DEFAULT_PRICE) {
val parts = currentPrice.toRationalNumber()
if (parts.second != null) {
if (parts.second!!.length < maximumFractionDigits) {
currentPrice += number
} else {
errorListener?.invoke()
}
} else {
if (parts.first.length < maximumIntegerDigits) {
currentPrice += number
} else {
errorListener?.invoke()
}
}
} else {
currentPrice = number.toString()
}
updatePrice()
}
fun addDecimalSeparator() {
if (maximumFractionDigits > 0 && !currentPrice.contains(decimalSeparator)) {
currentPrice += decimalSeparator
updatePrice()
}
}
fun removeLastNumber() {
if (currentPrice != DEFAULT_PRICE) {
currentPrice =
if (currentPrice.length > 1) {
if (currentPrice.last() == decimalSeparator) {
if (currentPrice.length > 2) {
currentPrice.dropLast(2)
} else {
DEFAULT_PRICE
}
} else {
currentPrice.dropLast(1)
}
} else {
DEFAULT_PRICE
}
}
updatePrice()
}
fun setPrice(value: Double?) {
if (value == null) {
resetPrice()
} else if (value != currentPrice.toDoubleOrNull()) {
currentPrice = value.toString()
updatePrice()
}
}
fun getPrice(): Double =
currentPrice.toDouble()
fun resetPrice() {
currentPrice = DEFAULT_PRICE
updatePrice()
}
fun setCurrency(currency: Currency) {
currencyFormatter.currency = currency
maximumIntegerDigits = currencyFormatter.maximumIntegerDigits
maximumFractionDigits = currencyFormatter.maximumFractionDigits
decimalSeparator = currencyFormatter.decimalFormatSymbols.decimalSeparator
updatePrice()
}
fun setValueListener(listener: (Double) -> Unit) {
this.valueListener = listener
}
fun setErrorListener(listener: () -> Unit) {
this.errorListener = listener
}
private fun updatePrice() {
if (currentPrice.isBlank()) currentPrice = DEFAULT_PRICE
val priceDouble = currentPrice.toDouble()
text = currencyFormatter.format(priceDouble)
valueListener?.invoke(priceDouble)
}
private fun String.toRationalNumber(): Pair<String, String?> {
val split = trim().split(decimalSeparator)
val integer = split.first()
val decimal = split.getOrNull(1)
return Pair(integer, decimal)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment