vid*_*ige 27 android localization internationalization units-of-measurement
我正在开发一个想要以厘米(cm)或英寸(")显示长度的应用程序.有没有办法从区域设置中选择正确的单位?无论如何我还要投入一个选项,以便用户可以覆盖区域设置.
美国,利比里亚和缅甸应使用英制单位和世界其他地区的正常单位.一种方法是在我自己的类中加入这个逻辑,但我更喜欢使用任何内置逻辑(如果可用).有什么指针吗?
vid*_*ige 47
最后我采取了以下解决方案.
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;
}
}
Run Code Online (Sandbox Code Playgroud)
例如,像这样使用它.
if (UnitLocale.getDefault() == UnitLocale.Imperial) convertToimperial();
Run Code Online (Sandbox Code Playgroud)
如果还需要转换方法,则可以将它们添加到UnitLocale的子类中.我只需要检测使用英制单位并将其发送到服务器.
使用ints over java对象具有极其微小的性能提升,并使代码更难阅读.比较java中的两个引用在速度上与比较两个引用相当ints.使用对象还允许我们向UnitLocale类或子类添加方法,例如convertToMetric等.
如果您愿意,也可以使用枚举.
这样做的或多或少完整的方法是这种方式。
科特林:
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
}
Run Code Online (Sandbox Code Playgroud)
请注意,英国和美国的帝国系统之间存在差异,有关详细信息,请参阅 wiki 文章。
对@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;
}
}
Run Code Online (Sandbox Code Playgroud)
另一个解决方案可能是为每个国家/地区创建资源文件夹,例如:[values_US] [values_LR] [values_MM],并将布尔资源更改为 true。然后从代码中读取该布尔资源。
在此处其他不错的解决方案的基础上,您还可以将其实现为 Locale 对象的 Kotlin 扩展函数:
fun Locale.isMetric(): Boolean {
return when (country.toUpperCase(this)) {
"US", "LR", "MM" -> false
else -> true
}
}
Run Code Online (Sandbox Code Playgroud)
这样,您需要做的就是调用:
val metric = Locale.getDefault().isMetric()
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
12547 次 |
| 最近记录: |