code小生,一个专注 Android 领域的技术平台

回复 Android 加入我的安卓技术群

作者:简简单单敲代码
链接:https://www.jianshu.com/p/2ec22e77fa94
声明:本文已获简简单单敲代码授权发表,转发等请联系原作者授权

测试提【将app语言设置为印尼语时,显示的价格小数点变成了逗号】这 bug,如图:

神奇

目前 APP 有中文,英文,繁体,马来文,印尼,泰语这几个国际化,在英文中文等语言下这个 bug 是不存在的,在印尼语的情况下是存在的。英文状态下如图:

英文状态

那么可以肯定是在国家化的时候出现的 bug,
先排查了一下,是在这行代码出现的问题:String.format("%.2f", price)

我们只需要修改成String.format(Locale.ENGLISH, "%.2f", price)这样就能解决这个 bug。

效果如下:

修复后

但是我们还是要看看为什么?

分析一下源码:
先看看String.format("%.2f", price)这行代码会调用

    public static String format(String format, Object... args) {        return new Formatter().format(format, args).toString();    }

继续跟

  public Formatter format(String format, Object ... args) {        return format(l, format, args);    } public Formatter format(Locale l, String format, Object ... args) {        ensureOpen();

        // index of last argument referenced        int last = -1;        // last ordinary index        int lasto = -1;

        FormatString[] fsa = parse(format);        for (int i = 0; i < fsa.length; i++) {            FormatString fs = fsa[i];            int index = fs.index();            try {                switch (index) {                case -2:  // fixed string, "%n", or "%%"                    fs.print(null, l);                    break;                case -1:  // relative index                    if (last < 0 || (args != null && last > args.length - 1))                        throw new MissingFormatArgumentException(fs.toString());                    fs.print((args == null ? null : args[last]), l);                    break;                case 0:  // ordinary index                    lasto++;                    last = lasto;                    if (args != null && lasto > args.length - 1)                        throw new MissingFormatArgumentException(fs.toString());                    fs.print((args == null ? null : args[lasto]), l);                    break;                default:  // explicit index                    last = index - 1;                    if (args != null && last > args.length - 1)                        throw new MissingFormatArgumentException(fs.toString());                    fs.print((args == null ? null : args[last]), l);                    break;                }            } catch (IOException x) {                lastException = x;            }        }        return this;    }

我们注意一下这个 l 的参数,是Locale的实例,这个类位于java.util.Locale下面。

我们看看这个l的初始化。

 /**     * Constructs a new formatter.     *     * <p> The destination of the formatted output is a {@link StringBuilder}     * which may be retrieved by invoking {@link #out out()} and whose     * current content may be converted into a string by invoking {@link     * #toString toString()}.  The locale used is the {@linkplain     * Locale#getDefault(Locale.Category) default locale} for     * {@linkplain Locale.Category#FORMAT formatting} for this instance of the Java     * virtual machine.     */    public Formatter() {        this(Locale.getDefault(Locale.Category.FORMAT), new StringBuilder());    }  /* Private constructors */    private Formatter(Locale l, Appendable a) {        this.a = a;        this.l = l;        this.zero = getZero(l);    }

这里是l是通过 Locale.getDefault(Locale.Category.FORMAT) 进行初始化的。

再看看String.format(Locale.ENGLISH, "%.2f", price)的调用源码。

 public static String format(Locale l, String format, Object... args) {        return new Formatter(l).format(format, args).toString();    }

在初始化Formatter的时候就直接传入了l这个对象。所以我们可以肯定String.format("%.2f", price)String.format(Locale.ENGLISH, "%.2f", price)最终差别在于这个Locale对象,一个是直接指明了需要的语言环境,这里是ENGLISH,一个是通过Locale.getDefault(Locale.Category.FORMAT) 去直接获取当前默认的语言环境,而在印尼语的时候,默认是印尼语。

现在知道了是由于是Locale导致的,那么就有新问题了,为什么Locale的区别会导致小数点变成了逗号?

明明是3.00结果给我整来一个3,00,这是在逗我??

黑人问号

所以我们再分析一下。在这个Locale类里面,其中会有一些默认的 Useful constant for language.


这个 createConstantAPI 是私有的。这个方法的新建是为了匹配资源文件的翻译的以及后面的系统的调用,但是印尼语不在其中。

  /**     * This method must be called only for creating the Locale.*     * constants due to making shortcuts.     */    private static Locale createConstant(String lang, String country) {        BaseLocale base = BaseLocale.createInstance(lang, country);        return getInstance(base, null);    }

总结

使用Locale类有定义,就不会出现这种情况。例如中文,英文肯定是正常的。不在Locale类定义,就会出现。

提醒

如果在使用 String.format(Locale.ENGLISH, "%.2f", price)这个方法的时候,千万要记得,如果使用了string资源文件的时候,如:String.format("%s", getResources().getString(R.string.xxxx));这样写会的话那么会全是英文。
可以分开写,这样的话就不会全是英文了。

示例代码:

String s = getResources().getString(R.string.xxxx);String.format("%s", s )

感谢你的阅读,如有问题欢迎指正!

国际化适配

Android 键盘适配-中英文适配

Android O 适配 Notification Channel

分享技术我是认真的

Android 国家化的坑 - 小数点变成逗号相关推荐

  1. android 使用String.format(%.2f,67.876)自已定义语言(俄语、西班牙语)会把小数点变为逗号...

    市场人员反映公司的app使用系统设置俄语.西班牙语,double数据会把小数点变为逗号.调试一下,是自定义的语言时候(例如,俄语.西班牙语)转换String.format("%.2f&quo ...

  2. 基于jQuery.i18n.properties插件实现前端页面国家化

    一.简介 在介绍jQuery.i18n.properties 之前,我们先来看一下什么是国际化.国家化英文单词为:Internationalization,又称 i18n,"i"为 ...

  3. Android Studio安装踩坑

    title: Android Studio安装踩坑 date: 2018-09-07 19:31:32 updated: tags: [Android,Android Studio,坑] descri ...

  4. 关于Android studio3.0的坑之butterknife 7.0.1(低版本)

    关于Android studio3.0的坑之butterknife 7.0.1(低版本) 我们在AS3.0里面是无法直接使用butterknife 内库插件的,会报错,如下图: 接下来看看怎么设置呢? ...

  5. 关于Android studio3.0的坑之butterknife 8.4.0

    关于Android studio3.0的坑之butterknife 8.4.0 大家都知道新版本问题很多,butterknife 8.4.0版本无法直接使用要配置很多东西: 首先得安装butterkn ...

  6. Android项目开发填坑记-Fragment的onAttach

    背景 现在Android开发多使用一个Activity管理多个Fragment进行开发,不免需要两者相互传递数据,一般是给Fragment添加回调接口,让Activity继承并实现. 回调接口一般都写 ...

  7. 【Android踩过的坑】5.android.content.res.Resources$NotFoundException: String resource ID #0x0

    [Android踩过的坑]5.android.content.res.Resources$NotFoundException: String resource ID #0x0 情况: TextView ...

  8. 【Android 踩过的坑】4.java.io.IOException: Cannot run program “/system/xbin/su“: error=2, No such file...

    [Android 踩过的坑]4. java.io.IOException: Cannot run program "/system/xbin/su": error=2, No su ...

  9. android 字体文件压缩,Android 字体使用踩坑指南

    Android 字体使用踩坑指南 最近项目改版,根据ui的设计,需要使用到三字体.在使用过程中遇到一些坑,于是有了这个避坑指南! 字体压缩 第一个坑!字体库的体积太大. 字体压缩的前提是要使用的内容是 ...

最新文章

  1. android 镜像 制作工具,手机rom只制作-镜像工厂app下载2.8安卓最新版-西西软件下载...
  2. 用pip安装GDAL时出错
  3. php stdin是什么意思,php:// input和php:// stdin之间有什么区别?
  4. jboss8日志级别设置_罐中研讨会:设置JBoss BPM Suite全日研讨会
  5. “中国工程设计大师”俞加康:为地铁耕耘“时不我待,只争朝夕”
  6. torch.randn
  7. java编程实现食堂饭卡刷卡_食堂饭卡管理系统设计方案报告.docx
  8. 类模板和模板类的关系
  9. FusionChartsFree调用json数据的简单例子
  10. android视频录制旋转,android – 录制的视频在上传到互联网后旋转90度
  11. 计算机应用物联网应用技术论文,物联网的关键技术及计算机物联网的应用研究...
  12. 基于hal的hcsr04使用注意事项(f103c8t6)
  13. java 计算月份和日期
  14. 语义分析(Semantic Parsing)调研
  15. node下载(使用nvm的方式)
  16. ORB SLAM2源码解读(三):Frame类
  17. 如果你要读一本真正普及“人工智能”的读物 | 赠书
  18. 数据预处理(纯干货,适合小白学习)
  19. 金仓数据库KingbaseES数据迁移
  20. 领英工具-领英精灵的批量加好友功能你真的会用吗?

热门文章

  1. 自己整理的前端开发面试题
  2. EasyExcel 使用和背景颜色样式(3.0以上的版本)
  3. Cadence Allegro(2):建立元器件Library
  4. 计算机二级试题怎么下载
  5. 85人教版高中英语第一册第十四课 WATCHING ANTS
  6. 学校计算机教室报损登记本,学校设施设备管理制度规定
  7. 敏捷项目管理实战之进度管理
  8. ubuntu20.04蚂蚁笔记(leanote)的使用
  9. java如何获取手机号码_java中如何提取一个字符串中的电话号码?
  10. 联想E440打开VT(虚拟化)