You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让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()
}

原因分析

  1. Locale.ROOT不支持会计格式:ROOT是中立区域,没有定义会计符号的显示规则,会计格式的括号展示依赖于具体区域的本地化配置。
  2. 紧凑符号与会计格式冲突: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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 19:38:41