32

我正在开发一个应用程序,它希望以厘米 (cm) 或英寸 (") 为单位显示长度。有没有办法从语言环境中选择正确的单位?无论如何,我也会输入一个选项,以便用户可以覆盖区域设置。

美国、利比里亚和缅甸应使用英制单位和世界其他地区的标准单位。一种方法是将此逻辑放入我自己的类中,但如果可用,我更喜欢使用任何内置逻辑。任何指针?

4

6 回答 6

51

最后我选择了以下解决方案。

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 等。

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

于 2011-10-22T16:09:32.967 回答
8

一个或多或少完整的方法是这种方式。

科特林:

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
    }

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

于 2018-11-06T15:09:49.050 回答
7

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

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

这样,您需要做的就是调用:

val metric = Locale.getDefault().isMetric()
于 2019-04-10T16:22:36.417 回答
6

LocaleData.getMeasurementSystem可从 API 级别 28 及更高级别获得。它返回您正在寻找的信息。

于 2020-04-16T04:43:17.260 回答
4
  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。然后从代码中读取该布尔资源。

于 2016-11-22T01:19:27.217 回答
2

只需让用户在设置菜单中选择首选单位即可。如果它是旅行用户,您不希望应用程序具有地理意识,IMO。

于 2011-02-04T13:08:44.493 回答