注意:这个答案是关于 vNext - 移植回 master 应该相当容易......该区域的差异不是那么大。
MvvmCross 中内置了一个文本本地化机制。
唯一使用它的公共示例是会议示例。
此示例包括共享的和 ViewModel 特定的 Json 文件 -请参阅
这些 Json 文件每个都包含简单的键值对,例如:
{
"Title":"SQLBits X",
"Welcome":"Welcome",
"Sessions":"Sessions",
"Sponsors":"Sponsors",
"Tweets":"Tweets",
"Favorites":"Favorites"
}
它们作为内容或资产链接到 Droid、Touch 和 WP……所有这些都由平台使用 ResourceLoader 插件访问。
为了在运行时使用这些 JSON 文件,核心项目将它们加载到TextProviderBuilder中:
protected override IDictionary<string, string> ResourceFiles
{
get
{
var dictionary = this.GetType()
.Assembly
.GetTypes()
.Where(t => t.Name.EndsWith("ViewModel"))
.Where(t => !t.Name.StartsWith("Base"))
.ToDictionary(t => t.Name, t => t.Name);
dictionary[Constants.Shared] = Constants.Shared;
return dictionary;
}
}
如果您愿意,显然可以在此处轻松加载其他 JSON 文件。我的一些应用程序具有以下情况并不少见:
- 错误文件
- 一般共享语句的文件
- 特定组件的文件
- 每个 ViewModel 一个文件
而其他人有:
国际化 - 完成后 - 通过加载一组不同的 JSON 文件来完成。通常所做的是首先加载默认集,然后加载增量覆盖 - 因此您可以加载英语作为默认值,Cat 作为覆盖,Cat-Lol 作为进一步细化。
有关这方面的一些讨论,请参见:
假设每个 ViewModel 有一个共享文件和一个文件,那么为了提供对 JSON 文本值的运行时访问,BaseViewModel 提供了 2 个属性:
public IMvxLanguageBinder TextSource
{
get { return new MvxLanguageBinder(Constants.GeneralNamespace, GetType().Name); }
}
public IMvxLanguageBinder SharedTextSource
{
get { return new MvxLanguageBinder(Constants.GeneralNamespace, Constants.Shared); }
}
这些属性在数据绑定中使用:
- 指定是否使用 SharedTextSource 或 TextSource 的路径
- MvxLanguageBinderConverter 作为转换器
- 文本键作为 ConverterParameter
例如,在 Droid 中,这是:
<TextView
style="@style/AboutPageBodyText"
local:MvxBind="{'Text':{'Path':'TextSource','Converter':'Language','ConverterParameter':'Title'}}"
/>
尽管在现代“瑞士”装订中,这将被写成:
<TextView
style="@style/AboutPageBodyText"
local:MvxBind="Text TextSource, Converter=Language, ConverterParameter='Title'"
/>
任何希望使用 Text 的代码也可以这样做 - 例如,请参阅 TimeAgo 文本是如何从 TimeAgoConverter.cs 中的资源字符串创建的,它 使用如下资源字符串:
{
"TimeAgo.JustNow":"just now",
"TimeAgo.SecondsAgo":"{0}s ago",
"TimeAgo.MinutesAgo":"{0}m ago",
"TimeAgo.HoursAgo":"{0}h ago",
"TimeAgo.DaysAgo":"{0}d ago",
"TimeAgo.Never":"never"
}
有效的代码是:
var valueToFormat = 42;
var whichFormat = "TimeAgo.DaysAgo";
var textProvider = this.GetService<IMvxTextProvider>();
var format = textProvider.GetText(Constants.GeneralNamespace, Constants.Shared, whichFormat);
return string.Format(format, valueToFormat)
语言 Binder 和 ValueConverter 是非常简单的代码
因此,如果您需要,请随意为您的应用构建更复杂的东西。
其他跨平台文本本地化技术可用 - 我自己特别想有一天尝试白话 - https://github.com/rdio/vernacular