Xamarin.Android:通过编程方式更改应用语言?

时间:2020-07-20 11:42:46

标签: c# android xamarin xamarin.android localization

我的strings.xmlvalues-en文件夹中有2个values-fr文件。当我从Android设置更改语言时,应用已正确本地化。

但是,有没有一种方法可以通过编程方式更改应用语言?以下代码(有关该主题的最新文章stackoverflow帖子建议)对本地化没有任何影响:

var locale = new Java.Util.Locale("fr");
Java.Util.Locale.Default = locale;
var context = Application.Context;
context.Resources.Configuration.Locale = locale;
    
BaseContext.ApplicationContext.CreateConfigurationContext(context.Resources.Configuration);
BaseContext.Resources.DisplayMetrics.SetTo(context.Resources.DisplayMetrics);

实际上,此代码后带有GetString(Resource.String.stringName)的字符串将保留为英文。

目标版本: Android 8.1(API 27-Oreo)

使用Android.Support.V7.App的AppCompat活动(仅在Android.Support.Design.Widget中使用FAB)

感谢您的帮助!

2 个答案:

答案 0 :(得分:0)

createConfigurationContext(configuration)还不够,我们需要获取此方法返回的上下文,然后在attachBaseContext方法中设置此上下文。

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

    private Context updateBaseContextLocale(Context context)
    {
        var locale = new Java.Util.Locale("sp");
        Java.Util.Locale.Default = locale;

        if (Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.N)
        {
            Configuration configuration = context.Resources.Configuration;
            configuration.SetLocale(locale);

            return context.CreateConfigurationContext(configuration);
        }
        else
        {
            Resources resources = context.Resources;
            Configuration configuration = resources.Configuration;
     #pragma warning disable CS0618 // Type or member is obsolete
            configuration.Locale = locale;
            resources.UpdateConfiguration(configuration, resources.DisplayMetrics);
     #pragma warning restore CS0618 // Type or member is obsolete

            return context;
        }         
    }

在OnCreate方法中获取字符串

   string title = GetString(Resource.String.TxtWelcome);

参考

https://stackoverflow.com/a/44571077/8187800

答案 1 :(得分:0)

override AttachBaseContext in your activity

受保护的覆盖无效void AttachBaseContext(Context @base){base.AttachBaseContext(MyContextWrapper.Wrap(@ base,PreferencesManager.Language));} 这样创建类MyContextWrapper:

公共类MyContextWrapper:ContextWrapper {

    public MyContextWrapper(Context @base) : base(@base)
    {
    }

    [SuppressWarnings(Value = new string[] { "deprecation" })]
    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);
        }
        if (!language.Equals("") && !sysLocale.Language.Equals(language))
        {
            Locale locale = new Locale(language);
            Category[] vals = null;
            if (Build.VERSION.SdkInt >= BuildVersionCodes.N)
            {
                vals = Locale.Category.Values();
            }
            else
            {
                config.SetLayoutDirection(locale);
            }
            if (vals != null && vals.Length > 0)
            {
                Locale.SetDefault(vals[0], 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);
    }

    [SuppressWarnings(Value = new string[] { "deprecation" })]
    public static Locale getSystemLocaleLegacy(Configuration config)
    {
        return config.Locale;
    }
    [TargetApi(Value = (int)BuildVersionCodes.N)]
    public static Locale getSystemLocale(Configuration config)
    {
        return config.Locales.Get(0);
    }

    [SuppressWarnings(Value = new string[] { "deprecation" })]
    public static void setSystemLocaleLegacy(Configuration config, Locale locale)
    {
        config.Locale = locale;
    }

    [TargetApi(Value = (int)BuildVersionCodes.N)]
    public static void setSystemLocale(Configuration config, Locale locale)
    {
        config.SetLocale(locale);
    }
}

Blockquote

在您的活动中: 受保护的重写void AttachBaseContext(Context @base) { base.AttachBaseContext(MyContextWrapper.Wrap(@base,PreferencesManager.Language)); }