Android印尼盾转多币种转换器数字格式问题求助
如何在Kotlin中格式化货币转换结果,避免指数形式并保留最多两位小数?
问题描述
我正在开发一款将印尼盾转换为12种其他货币的货币转换器,以欧元转换为例,期望得到如下格式的结果:
- 10印尼盾→0.001欧元
- 100印尼盾→0.006欧元
- 1000印尼盾→0.06欧元
- 100,000印尼盾→6欧元
- 1,000,000印尼盾→60欧元
- 10,000,000印尼盾→600欧元
我设置了输入字段,输入值后其他结果会自动更新,但当前显示结果会出现指数形式,希望将结果格式化为最多保留两位小数。附我的Kotlin代码如下:
class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) valeurIdr.addTextChangedListener(object : TextWatcher { override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) { if (s.toString().equals("")) { resultEuro.text=null } else { val idr = valeurIdr?.text.toString().toDouble() val euro = 0.000060 resultEuro?.setText((idr * euro).toString()) } } override fun beforeTextChanged( s: CharSequence, start: Int, count: Int, after: Int) { } override fun afterTextChanged(s: Editable) { // TODO Auto-generated method stub } }) } }
解决方案
问题出在直接调用Double.toString()上——当数值非常小的时候,Kotlin会默认用科学计数法(指数形式)来显示结果。我们可以用DecimalFormat类来精确控制输出格式,确保结果以普通小数形式展示,并且最多保留两位小数。
修改后的代码
import java.text.DecimalFormat class MainActivity : AppCompatActivity() { // 初始化DecimalFormat,模式"0.##"表示最多保留两位小数,无多余末尾零 private val decimalFormat = DecimalFormat("0.##") override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) valeurIdr.addTextChangedListener(object : TextWatcher { override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) { if (s.toString().trim().isEmpty()) { resultEuro.text = null } else { try { val idr = s.toString().toDouble() val euroRate = 0.000060 val euroAmount = idr * euroRate // 用DecimalFormat格式化结果,避免指数形式 resultEuro?.text = decimalFormat.format(euroAmount) } catch (e: NumberFormatException) { // 处理输入非数字的情况,比如输入字母或特殊字符 resultEuro?.text = "无效输入" } } } override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {} override fun afterTextChanged(s: Editable) {} }) } }
关键说明
DecimalFormat模式:
"0.##"的含义是:0:强制显示整数部分,即使是0也会显示##:最多显示两位小数,只有当小数部分有值时才会显示,不会出现末尾多余的零(比如结果是6.0的话,会显示为6而不是6.00)
如果你希望强制保留两位小数(比如6显示为6.00),可以把模式改成"0.00"。
异常处理:添加了
NumberFormatException的捕获,防止用户输入非数字内容导致崩溃,提升应用稳定性。避免科学计数法:
DecimalFormat默认不会使用科学计数法来展示常规范围内的数值,完美解决你遇到的指数形式问题。
替代方案(本地化适配)
如果你的应用需要适配不同地区的数字格式(比如有的地区用逗号做小数分隔符),可以用NumberFormat来实现:
private val numberFormat = NumberFormat.getInstance().apply { maximumFractionDigits = 2 minimumFractionDigits = 0 isGroupingUsed = false // 不需要千位分隔符的话设置为false }
然后用numberFormat.format(euroAmount)来格式化结果即可。
内容的提问来源于stack exchange,提问作者Marc75




