2017-05-04 16 views
0

我遵循documentation並使用顯示正確語言的resx文件,在Android上使用DI,我可以在我的應用程序中更改語言。 基本上在Android中,我添加了特定於平臺的代碼作爲文章本地化在發佈模式下使用「將程序集打包到本地代碼」不起作用

`[assembly:Dependency(typeof(UsingResxLocalization.Android.Localize))] 

namespace UsingResxLocalization.Android 
{ 
    public class Localize : UsingResxLocalization.ILocalize 
    { 
     public void SetLocale(CultureInfo ci) 
     { 
      Thread.CurrentThread.CurrentCulture = ci; 
      Thread.CurrentThread.CurrentUICulture = ci; 
     } 
     public CultureInfo GetCurrentCultureInfo() 
     { 
      var netLanguage = "en"; 
      var androidLocale = Java.Util.Locale.Default; 
      netLanguage = AndroidToDotnetLanguage(androidLocale.ToString().Replace("_", "-")); 
      // this gets called a lot - try/catch can be expensive so consider caching or something 
      System.Globalization.CultureInfo ci = null; 
      try 
      { 
       ci = new System.Globalization.CultureInfo(netLanguage); 
      } 
      catch (CultureNotFoundException e1) 
      { 
       // iOS locale not valid .NET culture (eg. "en-ES" : English in Spain) 
       // fallback to first characters, in this case "en" 
       try 
       { 
        var fallback = ToDotnetFallbackLanguage(new PlatformCulture(netLanguage)); 
        ci = new System.Globalization.CultureInfo(fallback); 
       } 
       catch (CultureNotFoundException e2) 
       { 
        // iOS language not valid .NET culture, falling back to English 
        ci = new System.Globalization.CultureInfo("en"); 
       } 
      } 
      return ci; 
     } 
     string AndroidToDotnetLanguage(string androidLanguage) 
     { 
      var netLanguage = androidLanguage; 
      //certain languages need to be converted to CultureInfo equivalent 
      switch (androidLanguage) 
      { 
       case "ms-BN": // "Malaysian (Brunei)" not supported .NET culture 
       case "ms-MY": // "Malaysian (Malaysia)" not supported .NET culture 
       case "ms-SG": // "Malaysian (Singapore)" not supported .NET culture 
        netLanguage = "ms"; // closest supported 
        break; 
       case "in-ID": // "Indonesian (Indonesia)" has different code in .NET 
        netLanguage = "id-ID"; // correct code for .NET 
        break; 
       case "gsw-CH": // "Schwiizertüütsch (Swiss German)" not supported .NET culture 
        netLanguage = "de-CH"; // closest supported 
        break; 
        // add more application-specific cases here (if required) 
        // ONLY use cultures that have been tested and known to work 
      } 
      return netLanguage; 
     } 
     string ToDotnetFallbackLanguage(PlatformCulture platCulture) 
     { 
      var netLanguage = platCulture.LanguageCode; // use the first part of the identifier (two chars, usually); 
      switch (platCulture.LanguageCode) 
      { 
       case "gsw": 
        netLanguage = "de-CH"; // equivalent to German (Switzerland) for this app 
        break; 
        // add more application-specific cases here (if required) 
        // ONLY use cultures that have been tested and known to work 
      } 
      return netLanguage; 
     } 
    } 
}` 

在PCL代碼中所描述我有

namespace myApp.Resx 
{ 

    /// <summary> 
    /// Implementations of this interface MUST convert iOS and Android 
    /// platform-specific locales to a value supported in .NET because 
    /// ONLY valid .NET cultures can have their RESX resources loaded and used. 
    /// </summary> 
    /// <remarks> 
    /// Lists of valid .NET cultures can be found here: 
    /// http://www.localeplanet.com/dotnet/ 
    /// http://www.csharp-examples.net/culture-names/ 
    /// You should always test all the locales implemented in your application. 
    /// </remarks> 
    public interface ILocalize 
    { 
     /// <summary> 
     /// This method must evaluate platform-specific locale settings 
     /// and convert them (when necessary) to a valid .NET locale. 
     /// </summary> 
     CultureInfo GetCurrentCultureInfo(); 

     /// <summary> 
     /// CurrentCulture and CurrentUICulture must be set in the platform project, 
     /// because the Thread object can't be accessed in a PCL. 
     /// </summary> 
     void SetLocale(CultureInfo ci); 
    } 

    /// <summary> 
    /// Helper class for splitting locales like 
    /// iOS: ms_MY, gsw_CH 
    /// Android: in-ID 
    /// into parts so we can create a .NET culture (or fallback culture) 
    /// </summary> 
    public class PlatformCulture 
    { 
     public PlatformCulture(string platformCultureString) 
     { 
      if (String.IsNullOrEmpty(platformCultureString)) 
       throw new ArgumentException("Expected culture identifier", "platformCultureString"); // in C# 6 use nameof(platformCultureString) 

      PlatformString = platformCultureString.Replace("_", "-"); // .NET expects dash, not underscore 
      var dashIndex = PlatformString.IndexOf("-", StringComparison.Ordinal); 
      if (dashIndex > 0) 
      { 
       var parts = PlatformString.Split('-'); 
       LanguageCode = parts[0]; 
       LocaleCode = parts[1]; 
      } 
      else 
      { 
       LanguageCode = PlatformString; 
       LocaleCode = ""; 
      } 
     } 
     public string PlatformString { get; private set; } 
     public string LanguageCode { get; private set; } 
     public string LocaleCode { get; private set; } 
     public override string ToString() 
     { 
      return PlatformString; 
     } 
    } 
} 

然後在我的PCL代碼,我能夠覆蓋文化與代碼低於

string name = Helpers.Settings.PreferredLanguage == "en" ? "en-US" : Helpers.Settings.PreferredLanguage + "-" + Helpers.Settings.PreferredLanguage.ToUpper(); 
         currentCultureInfo = new System.Globalization.CultureInfo(name); 
         Xamarin.Forms.DependencyService.Get<Resx.ILocalize>().SetLocale(currentCultureInfo);      

       Resx.AppRes.Culture = currentCultureInfo; 

此代碼實現工作正常,當我在調試和發佈模式下運行。 但使用「將程序集打包到本機代碼」,它無法在發佈模式下工作。 如果我刪除此選項的檢查,它工作正常。 可能的問題是什麼?我不知道如何跟蹤這個。我試過使用Android設備監視器,但它沒有顯示太多。 enter image description here

配置看起來像上面那樣。

編輯:當我啓用,「啓用開發人員儀表」在發佈模式下,它也可以。

回答

1

很明顯,在link上已經存在一個針對此問題的現有錯誤。在bug被xamarin修復之前,解決方法與鏈接上的建議一樣。在MainActivity的OnCreate功能中爲每種語言添加一行

System.Reflection.Assembly.LoadFile("de-DE\\AppName.resources.dll");