Reputation: 473
I wanna change the locale in my APP... I read a lot of articles and now I have this code, it doesn't work and doesn't give me an error:
My LanguageActivity:
public class 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);
}
}
My BaseActivity:
public class BaseActivity : Activity {
protected override void AttachBaseContext(Context @base)
{
base.AttachBaseContext(LanguageManager.LoadLanguage(@base));
}
}
My LanguageManager:
public class 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;
}
}
Why doesn't it work? I read this and this. They're using the same method!
PS1: I have values-fa folder and Strings.xml there. When I change the language in the phone's setting, I see the changes. So it works when I change the locale on the phone!
PS2: I simplified the code, that's why I removed the SharedPreference part in LanguageActivity!
PS3: Download the project: Download
Upvotes: 0
Views: 823
Reputation: 15001
sorry for reply so later,i'm off duty at weekends,i test your project.the issue is you didn't let your LoginActivity
extends BaseActivity
.you should let all activities extends BaseActivity
.
change
public class LoginActivity : Activity
to
public class LoginActivity : BaseActivity
Upvotes: 1
Reputation: 16547
For Xamarin.Android you can do it like this :
Create your own context wrapper like this :
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);
}
}
Add the following code to your activities:
protected override void AttachBaseContext(Context @base)
{
try
{
base.AttachBaseContext(MyContextWrapper.wrap(@base,"Your_language"));
}
catch{}
}
Make sure to restart the current activity every time your language changes.
Also, try updating my code as per your language requirements
Goodluck,
Feel free to get back if you have queries
Upvotes: 0
Reputation: 820
for the record, i have done this in the past and changing language in the app is a bad idea. it never really works well, and usually brings alot of bugs. Its much better to just let the app language be determined by the phones language setting.
if you really have to change language via the app though you need to set the locale in the configuration:
Configuration config = BaseContext.Resources.Configuration;
config.Locale = myLocale;
BaseContext.Resources.UpdateConfiguration(config, BaseContext.Resources.DisplayMetrics);
where MyLocale is the language to set, for example
var myLocale = new Locale("en");
edit: updated to xamarin code
Upvotes: 0