Xamarin Android 语言环境没有改变

Xamarin Android Locale doesn't change

我想在我的应用程序中更改语言环境...我阅读了很多文章,现在我有了这段代码,它不起作用,也没有给我一个错误:

  1. 我的语言Activity:

    public class 语言Activity : BaseActivity {

    protected override void OnCreate(Bundle savedInstanceState)
    {
        base.OnCreate(savedInstanceState);
        SetContentView(Resource.Layout.Language);
    
        LanguageManager.ChangeLanguage(this, "fa");
    
        Intent intent = new Intent(this, typeof(MainActivity));
        intent.SetFlags(ActivityFlags.ClearTask | ActivityFlags.NewTask);
        StartActivity(intent);
    }
    

    }

  2. 我的基地Activity:

    public class 基础Activity : Activity {

    protected override void AttachBaseContext(Context @base)
    {
        base.AttachBaseContext(LanguageManager.LoadLanguage(@base));
    }
    

    }

  3. 我的语言管理器:

    public class 语言管理器 {

    private const string MYLANGUAGE = "myLanguage";
    private const string MYPREF = "myPreference";
    
    public static Context LoadLanguage(Context context)
    {
        var loadedLanguage = GetLanguage(context, Locale.Default.Language);
        return ChangeLanguage(context, loadedLanguage);
    }
    
    public static Context ChangeLanguage(Context context, string language)
    {
        SaveLanguage(context, language);
        if (Build.VERSION.SdkInt >= BuildVersionCodes.N)
        {
            return ChangeForAPI24(context, language);
        }
        return ChangeForLegacy(context, language);
    }
    
    private static string GetLanguage(Context context, string Language)
    {
        var privatePreference = context.GetSharedPreferences(MYPREF, FileCreationMode.Private);
        return privatePreference.GetString(MYLANGUAGE, Language);
    }
    
    private static void SaveLanguage(Context context, string language)
    {
        var privatePreference = context.GetSharedPreferences(MYPREF, FileCreationMode.Private);
        var editor = privatePreference.Edit();
        editor.PutString(MYLANGUAGE, language);
        editor.Apply();
    }
    
    private static Context ChangeForAPI24(Context context, string language)
    {
        // for api >= 24
        Locale locale = new Locale(language);
        Locale.Default = locale;
    
        var configuration = context.Resources.Configuration;
        configuration.SetLocale(locale);
        configuration.SetLayoutDirection(locale);
    
        return context.CreateConfigurationContext(configuration);
    }
    
    private static Context ChangeForLegacy(Context context, string language)
    {
        var locale = new Locale(language);
        Locale.Default = locale;
        var resources = context.Resources;
        var configuration = resources.Configuration;
        configuration.Locale = locale;
        resources.UpdateConfiguration(configuration, resources.DisplayMetrics);
        return context;
    }
    

    }

为什么不起作用?我读 this and this。他们使用相同的方法!

PS1:我有 values-fa 文件夹和 Strings.xml。当我在 phone 的设置中更改语言时,我看到了更改。因此,当我更改 phone!

上的语言环境时它会起作用

PS2:我简化了代码,这就是为什么我删除了 LanguageActivity!

中的 SharedPreference 部分的原因

PS3:下载项目:Download

郑重声明,我过去曾这样做过,在应用程序中更改语言不是个好主意。它从来没有真正发挥作用,而且通常会带来很多错误。最好让应用语言由手机语言设置决定。

如果您确实需要通过应用程序更改语言,尽管您需要在配置中设置语言环境:

Configuration config = BaseContext.Resources.Configuration;
config.Locale = myLocale;
BaseContext.Resources.UpdateConfiguration(config, BaseContext.Resources.DisplayMetrics);

其中 MyLocale 是要设置的语言,例如

var myLocale = new Locale("en");

编辑:更新为 xamarin 代码

对于 Xamarin.Android 你可以这样做:

  • 像这样创建您自己的上下文包装器:

     public class MyContextWrapper : ContextWrapper
    {
       public MyContextWrapper(Context context) : base(context)          
       {
    
       }
    public static Locale getSystemLocaleLegacy(Configuration config)
    {
        return config.Locale;
    }
    public static Locale getSystemLocale(Configuration config)
    {
        return config.Locales.Get(0);
    }
    public static void setSystemLocaleLegacy(Configuration config, Locale locale)
    {
        config.SetLocale(locale);
        config.SetLayoutDirection(locale);
    }
    public static void setSystemLocale(Configuration config, Locale locale)
    {
        config.SetLocale(locale);
        config.SetLayoutDirection(locale);
    }
    
    public static ContextWrapper wrap(Context context, string language)
    {
        Configuration config = context.Resources.Configuration;
        Locale sysLocale = null;
        if (Build.VERSION.SdkInt >= BuildVersionCodes.N)
        {
            sysLocale = getSystemLocale(config);
        }
        else
        {
            sysLocale = getSystemLocaleLegacy(config);
        }
    
        Locale locale;
    
        if (language == "en")
        {
            locale = new Locale(language, "US");
        }
        else if (language == "zh")
        {
            locale = new Locale(language, "CN");
        }
        else
        {
            locale = new Locale("en", "US");
        }
    
        Locale.Default = (locale);
    
        if (Build.VERSION.SdkInt >= BuildVersionCodes.N)
        {
            setSystemLocale(config, locale);
        }
        else
        {
            setSystemLocaleLegacy(config, locale);
        }
    
        if (Build.VERSION.SdkInt >= BuildVersionCodes.JellyBeanMr1)
        {
            context = context.CreateConfigurationContext(config);
        }
        else
        {
            context.Resources.UpdateConfiguration(config, context.Resources.DisplayMetrics);
        }
    
        return new MyContextWrapper(context);
    }
    

    }

  • 将以下代码添加到您的活动中:

     protected override void AttachBaseContext(Context @base)
     {
        try
        {              
            base.AttachBaseContext(MyContextWrapper.wrap(@base,"Your_language"));
        }
        catch{}
     }
    

确保每次您的语言更改时重新启动当前 activity。

此外,尝试根据您的语言要求更新我的代码

祝你好运,

如果您有任何疑问,请随时回来

抱歉这么晚回复,我周末下班,我测试你的 project.the 问题是你没有让你的 LoginActivity 延长 BaseActivity。你应该让所有活动扩展 BaseActivity.

改变

public class LoginActivity : Activity

public class LoginActivity : BaseActivity