在开发中有时候会遇到输入金额的情况,对于金额的显示需要注意比较多的情况,
例如:
- 金额不能以0开头
- 不能有多个小数点
- 小数点后面只保留2位数
- 金额较大的时候做分号分割等等
如果还涉及到部分计算,也得注意计算结果是否正确等等情况
因为项目里面涉及到,目前也使用稳定,所以将相关代码分享出来,自己也再熟悉一遍。
以下是相关代码:
edit_money?.addTextChangedListener(object : TextWatcher {
override fun afterTextChanged(s: Editable?) {
}
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
var str = edit_money?.text?.toString()!!.trim()
//用于处理多个小数点输入问题
if (!TextUtils.isEmpty(str) && str.indexOf(".") != str.lastIndexOf(".")) {
edit_money?.setText(lastInput)
edit_money?.setSelection(edit_money?.text!!.length)//将光标移至文字末尾
return
}
//控制输入时只能输入1个0
if (!TextUtils.isEmpty(str) && str == "00") {
edit_money?.setText("0")
edit_money?.setSelection(edit_money?.text!!.length)//将光标移至文字末尾
return
}
//控制输入时第一个为0第二位不为.的情况
if (!TextUtils.isEmpty(str) && str.length >= 2 && str.indexOf("0") == 0 && str.indexOf(".") != 1) {
edit_money?.setText(str.substring(1, str.length))
edit_money?.setSelection(edit_money?.text!!.length)//将光标移至文字末尾
return
}
lastInput = str
//用于处理限制输入小数点后2位问题
val index = edit_money?.text?.indexOf(".")
if (index!! > 0 && index < edit_money?.text?.length!! - 3) {
val str = edit_money?.text?.substring(0, edit_money?.text?.toString()?.trim()?.indexOf(".")!! + 3)
edit_money?.setText(str)
edit_money?.setSelection(edit_money?.text!!.length)//将光标移至文字末尾
}
if (index == 0) {
edit_money?.setText("0" + edit_money?.text!!)
edit_money?.setSelection(edit_money?.text!!.length)//将光标移至文字末尾
}
var pricestr = edit_money?.text.toString().trim()
if (!TextUtils.isEmpty(pricestr)) {
//todo 获取到价格之后的处理
} else {
//todo 没有相关输入的处理
}
}
})
关于相关金额计算的问题,由于代码本身的问题,一些计算是不正确的,跟结果会有一定偏差,所以对于计算使用了以下工具类处理:
import java.math.BigDecimal
import java.math.RoundingMode
/**
* 用于double类型直接计算,以保证精度正确
*
* @author 陈聪 2018-01-30 11:55
*/
object CalcUtils {
val TYPE_ADD = 0x00 // 加法
val TYPE_MULTIPLY = 0x01 // 乘法
val TYPE_DIVIDE = 0x02 // 除法
val TYPE_SUBTRACT = 0x03 // 减法
/**
* 加法
* @param a
* @param b
* @return
*/
fun add(a: Double?, b: Double?): Double? {
return calc(a, b, -1, TYPE_ADD, null)
}
/**
* 减法
* @param a
* @param b
* @return
*/
fun sub(a: Double?, b: Double?): Double? {
return calc(a, b, -1, TYPE_SUBTRACT, null)
}
/**
* 乘法
* @param a
* @param b
* @return
*/
fun multiply(a: Double?, b: Double?): Double? {
return calc(a, b, -1, TYPE_MULTIPLY, null)
}
/**
* 除法
* @param a
* @param b
* @return
*/
fun divide(a: Double?, b: Double?): Double? {
return calc(a, b, -1, TYPE_DIVIDE, null)
}
/**
* 乘法
* @param a
* @param b
* @param scale 小数点后保留的位数
* @param mode 保留的模式
* @return
*/
fun multiply(a: Double?, b: Double?, scale: Int, mode: RoundingMode): Double? {
return calc(a, b, scale, TYPE_MULTIPLY, mode)
}
/**
* 除法
* @param a
* @param b
* @param scale 小数点后保留的位数
* @param mode 保留的模式
* @return
*/
fun divide(a: Double?, b: Double?, scale: Int, mode: RoundingMode): Double? {
return calc(a, b, scale, TYPE_DIVIDE, mode)
}
/**
* 计算
* @param a
* @param b
* @param scale
* @param type
* @param mode
* @return
*/
private fun calc(a: Double?, b: Double?, scale: Int, type: Int, mode: RoundingMode?): Double? {
var result: BigDecimal? = null
val bgA = BigDecimal(a.toString())
val bgB = BigDecimal(b.toString())
when (type) {
TYPE_ADD -> result = bgA.add(bgB)
TYPE_MULTIPLY -> result = bgA.multiply(bgB)
TYPE_DIVIDE -> try {
result = bgA.divide(bgB)
} catch (e: Exception) {// 防止无限循环而报错 采用四舍五入保留3位有效数字
result = bgA.divide(bgB, 3, RoundingMode.HALF_DOWN)
}
TYPE_SUBTRACT -> result = bgA.subtract(bgB)
}
if (mode == null) {
if (scale != -1) {
result = result!!.setScale(scale)
}
} else {
if (scale != -1) {
result = result!!.setScale(scale, mode)
}
}
return result!!.toDouble()
}
}
相关代码使用的是kotlin,若有看不懂的可以联系我。
QQ:617909447
若想学习kotlin的可以加以下QQ群:329673958
网友评论