如何让NumberFormatter输出带括号格式的负数数值?
问题:NumberFormatter会计符号显示不生效,负数仍用负号而非括号
需求:让负数金额以括号包裹的形式展示(如A$ (23.89)),但设置SignDisplay.ACCOUNTING相关枚举后,实际输出还是-A$ 23.89,尝试了ACCOUNTING_NEGATIVE、ACCOUNTING_ALWAYS均无效。
使用的代码:
override fun toString(): String { return NumberFormatter.withLocale(Locale.ROOT) .notation(Notation.compactShort()) .unit(currency) .precision(Precision.currency(Currency.CurrencyUsage.STANDARD)) // NEW! .sign(NumberFormatter.SignDisplay.ACCOUNTING) .format(rawValue) .toString() }
原因分析
- Locale.ROOT不支持会计格式:ROOT是中立区域,没有定义会计符号的显示规则,会计格式的括号展示依赖于具体区域的本地化配置。
- 紧凑符号与会计格式冲突:
Notation.compactShort()(紧凑缩写格式)的格式化逻辑可能会覆盖或忽略会计符号的设置,部分版本的API不支持两者同时生效。
解决方案
方案1:更换支持会计格式的Locale,移除紧凑符号
如果不需要紧凑缩写,直接使用对应货币的区域Locale,让会计格式生效:
override fun toString(): String { return NumberFormatter.withLocale(Locale("en", "AU")) // 澳元对应区域 .unit(currency) .precision(Precision.currency(Currency.CurrencyUsage.STANDARD)) .sign(NumberFormatter.SignDisplay.ACCOUNTING) .format(rawValue) .toString() }
方案2:保留紧凑符号,手动处理负数格式
如果必须使用紧凑缩写,通过字符串替换实现括号包裹:
override fun toString(): String { val formatted = NumberFormatter.withLocale(Locale.ROOT) .notation(Notation.compactShort()) .unit(currency) .precision(Precision.currency(Currency.CurrencyUsage.STANDARD)) .format(rawValue) .toString() return if (rawValue < 0) { // 匹配负号+货币符号+数值的格式,替换为货币符号+(数值) formatted.replace(Regex("-(\\p{Sc}) (\\d+.+)"), "$1 ($2)") } else { formatted } }
补充说明
如果使用的是androidx.core库的NumberFormatter,早期版本可能存在同时使用紧凑符号和会计符号的bug,此时手动替换是更稳定的方案。
内容的提问来源于stack exchange,提问作者Hakanai
相关产品推荐
相关产品推荐

