Xamarin iOS本地化使用.NET

本文关键字:NET 本地化 iOS Xamarin | 更新日期: 2024-09-25 15:25:02

我正试图在Xamarin iOS/Android项目的可移植类库中使用.NET本地化。我遵循了以下步骤:

如何在C#中使用本地化

并且有如下代码:

string sText = strings.enter_movie_name;
Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo("fr");
sText = strings.enter_movie_name;
lblEnterMovieName.Text = sText;

我也试过:

ResourceManager resman = new ResourceManager(typeof(MyApplication.strings));
string sText = resman.GetString("enter_movie_name", new CultureInfo("fr"));

我创建了字符串.resx,其中enter_movie_name等于"enter movie name:",字符串.fr.resx等于"Entre la movie name:"

但是,sText总是以"输入电影名称:"结尾。我好像搞不出"Entre la movie name:"这个版本。

我也在跨平台本地化上看到了这个帖子,但没能解决。我也不想在Xamarin.iOS上的本地化中使用iOS特定版本,因为我希望能够从独立于平台的库中获取字符串。

有人能指出我哪里错了吗?

Xamarin iOS本地化使用.NET

我创建了一个有点难看的解决方案,但它确实有效。我所做的是在我的可移植类库(PCL)中创建一个名为"字符串"的文件夹,并在其中创建名为:的文件

  • 字符串.resx
  • 字符串_fr.resx
  • 字符串_ja_JP.resx

我已经将所有设置为嵌入式资源,并使用自定义工具ResXFileCodeGenerator。这意味着我为每种语言都有一个单独的资源DLL。

在iOS中,我可以通过调用来获取区域设置

string sLocale = NSLocale.CurrentLocale.LocaleIdentifier;

我想有一个使用Locale的Android等效程序,但我不知道它是什么。

这给了我一个类似"ja_JP"、"fr_fr"或"en_GB"的字符串(注意它们是下划线,而不是破折号)。然后,我将其与我创建的以下静态类一起使用,以检索适当的资源管理器并从中获取字符串

如果给定一个区域设置aa_BB,它首先查找字符串_aa_BB,然后查找字符串_aa,再查找字符串。

public static class Localise
{
    private const string STRINGS_ROOT = "MyPCL.strings.strings";
    public static string GetString(string sID, string sLocale)
    {
        string sResource = STRINGS_ROOT + "_" + sLocale;
        Type type = Type.GetType(sResource);
        if (type == null)
        {
            if (sLocale.Length > 2) {
                sResource = STRINGS_ROOT + "_" + sLocale.Substring(0, 2); // Use first two letters of region code
                type = Type.GetType(sResource);
            }
        }
        if (type == null) {
            sResource = STRINGS_ROOT;
            type = Type.GetType(sResource);
            if (type == null)
            {
                System.Diagnostics.Debug.WriteLine("No strings resource file when looking for " + sID + " in " + sLocale);
                return null; // This shouldn't ever happen in theory
            }
        }
        ResourceManager resman = new ResourceManager(type);
        return resman.GetString(sID);
    }
}

如何使用(参考上述代码)的一个例子是:

string sText = Localise.GetString("enter_movie_name", sLocale);
lblEnterMovieName.Text = sText;

这样做的一个显著缺点是,所有视图都需要用程序设置文本,但也有好处,即翻译可以一次性完成,然后在许多平台上重复使用。它们也在自己的DLL中与主代码保持分离,因此可以在必要时单独重新编译。

我创建了一个类似于已接受答案的解决方案,但使用的是txt文件,而不是Resx和nuget:https://github.com/xleon/I18N-Portable.这里的博客文章。

其他改进包括:

  • "anyKey".Translate(); // from anywhere
  • 自动检测当前区域性
  • 获取支持的翻译列表:List<PortableLanguage> languages = I18N.Current.Languages;
  • 支持Mvvm框架/Xamarin.Forms中的数据绑定
  • 等等