Xamarin Android Locale не меняется - PullRequest
       10

Xamarin Android Locale не меняется

0 голосов
/ 17 октября 2019

Я хочу изменить локаль в моем приложении ... Я прочитал много статей, и теперь у меня есть этот код, он не работает и не выдает ошибку:

  1. Мой LanguageActivity :

    открытый класс LanguageActivity: 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. МойBaseActivity :

    открытый класс BaseActivity: действие {

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

    }

  3. My LanguageManager :

    открытый класс LanguageManager {

    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;
    }
    

    }

Почему он не работает? Я прочитал это и это . Они используют один и тот же метод!

PS1: у меня есть папка values-fa и Strings.xml там. Когда я меняю язык в настройках телефона, я вижу изменения. Так что это работает, когда я меняю локаль на телефоне!

PS2: я упростил код, поэтому я удалил часть SharedPreference в LanguageActivity!

PS3: Скачать проект: Скачать

Ответы [ 3 ]

1 голос
/ 21 октября 2019

извините за ответ, так что позже, по выходным я ухожу с работы, я проверяю ваш проект. Проблема в том, что вы не позволили своему LoginActivity расширению BaseActivity. Вам следует разрешить всем действиям расширение BaseActivity.

изменить

public class LoginActivity : Activity

на

public class LoginActivity : BaseActivity
0 голосов
/ 17 октября 2019

Для 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{}
     }
    

Обязательно перезапускайте текущее действие каждый раз, когда меняется ваш язык.

Кроме того, попробуйте обновить мой код в соответствии с требованиями вашего языка

Goodluck,

Не стесняйтесь вернуться, если у вас есть вопросы

0 голосов
/ 17 октября 2019

для записи, я делал это в прошлом, и изменение языка в приложении - плохая идея. это никогда не работает хорошо, и обычно приносит много ошибок. Гораздо лучше просто позволить языку приложения определять языковые настройки телефона.

, если вам действительно нужно изменить язык через приложение, хотя вам нужно установить языковой стандарт в конфигурации:

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

где MyLocale - это язык, который нужно установить, например,

var myLocale = new Locale("en");

edit: обновлено до кода xamarin

...