使用区域设置来检测是否使用英制单位

问题描述 投票:22回答:5

我正在开发一个想要以厘米(cm)或英寸(“)显示长度的应用程序。有没有办法从区域设置中选择正确的单位?无论如何我还要投入一个选项,以便用户可以覆盖区域设置。

美国,利比里亚和缅甸应使用英制单位和世界其他地区的正常单位。一种方法是在我自己的类中加入这个逻辑,但我更喜欢使用任何内置逻辑(如果可用)。有什么指针吗?

android localization internationalization units-of-measurement
5个回答
46
投票

最后我采取了以下解决方案。

public class UnitLocale {
    public static UnitLocale Imperial = new UnitLocale();
    public static UnitLocale Metric = new UnitLocale();

    public static UnitLocale getDefault() {
            return getFrom(Locale.getDefault());
    }
    public static UnitLocale getFrom(Locale locale) {
        String countryCode = locale.getCountry();
        if ("US".equals(countryCode)) return Imperial; // USA
        if ("LR".equals(countryCode)) return Imperial; // Liberia
        if ("MM".equals(countryCode)) return Imperial; // Myanmar
        return Metric;
    }
}

例如,像这样使用它。

if (UnitLocale.getDefault() == UnitLocale.Imperial) convertToimperial();

如果还需要转换方法,则可以将它们添加到UnitLocale的子类中。我只需要检测使用英制单位并将其发送到服务器。

在java对象上使用ints具有极其微小的性能提升,并使代码更难以阅读。比较java中的两个引用在速度上与比较两个ints相当。同样使用对象允许我们将方法添加到UnitLocale类或子类,例如convertToMetric等。

如果您愿意,也可以使用枚举。


3
投票
  1. 编程

从@vidstige对解决方案进行小幅改进

我会使用getCountry()。toUpperCase()来保证安全,并将检查更改为交换机以获得更干净的代码。像这样的东西:

public static UnitLocale getFrom(Locale locale) {
    String countryCode = locale.getCountry().toUpperCase();
    switch (countryCode) {
        case "US":
        case "LR":
        case "MM":
            return Imperial;
        default:
            return Metric;
    }
}
  1. 来自资源

另一个解决方案可能是为每个国家/地区创建资源文件夹,例如:[values_US] [values_LR] [values_MM],布尔资源更改为true。然后从代码中读取该布尔资源。


2
投票

只需让用户选择设置菜单中的首选单位即可。如果是旅行用户,您不希望应用程序在地理上有所了解,IMO。


2
投票

或多或少完成这种方式就是这样。

科特林:

private fun Locale.toUnitSystem() =
    when (country.toUpperCase()) {
        // https://en.wikipedia.org/wiki/United_States_customary_units
        // https://en.wikipedia.org/wiki/Imperial_units
        "US" -> UnitSystem.IMPERIAL_US
        // UK, Myanmar, Liberia, 
        "GB", "MM", "LR" -> UnitSystem.IMPERIAL
        else -> UnitSystem.METRIC
    }

请注意,英国和美国英制系统之间存在差异,有关详细信息,请参阅维基文章。


2
投票

在此处基于其他好的解决方案,您还可以将其实现为Locale对象的Kotlin扩展函数:

fun Locale.isMetric(): Boolean {
    return when (country.toUpperCase()) {
        "US", "LR", "MM" -> false
        else -> true
    }
}

这样,你需要做的就是打电话:

val metric = Locale.getDefault().isMetric()
© www.soinside.com 2019 - 2024. All rights reserved.