Oiproks
Oiproks

Reputation: 794

Unable to change app language at runtime on Xamarin Forms -> Android

I'm developing a crossplatform app using Xamarin Forms, primary target Android. The app I'm working on refers to .resx files for languages. The translations works fine as the phone is set to different langauges.

How can I switch languages from the app settings at runtime on the fly?

I tried using DependencyService to call a function on Android side, but, despite returning with no error, it doesn't change the language.

C# project

bool test = DependencyService.Get<ILanguageService>().SetLanguage(selectedLang.StringValue);

Android Project

[assembly: Dependency(typeof(LanguageService))]
namespace MyLangApp.Droid.Service
{
    public class LanguageService:ILanguageService
    {
        public bool SetLanguage(string lang = "")
        {
            try
            {
                Locale locale = string.IsNullOrEmpty(lang) ? new Locale("en-US") : new Locale(lang);
                Locale.Default = locale;
                var config = new Android.Content.Res.Configuration();
                config.Locale = locale;
                var context = Android.App.Application.Context;
                context.Resources.UpdateConfiguration(config, context.Resources.DisplayMetrics);
                return true;
            }
            catch
            {
                return false;
            }
        }
    }
}

Upvotes: 2

Views: 2577

Answers (2)

Kevin Mueller
Kevin Mueller

Reputation: 668

Take a look at CurrentCulture and CurrentUiCulture.

As far as I remember, you can set them at runtime.

Upvotes: 1

Mihail Duchev
Mihail Duchev

Reputation: 4821

I will guess that you are using i18n with a MarkupExtension. If so, then you can dynamically change the culture inside the Translate extension class' ctor.

namespace ResxLocalize
{
    [ContentProperty("Text")]
    public class TranslateExtension : IMarkupExtension
    {
        private readonly CultureInfo ci;
        private const string ResourceId = "MyApp.Resources.R";

        public TranslateExtension()
        {
            if (Device.RuntimePlatform == Device.iOS || Device.RuntimePlatform == Device.Android)
            {
                // SET YOUR CULTURE HERE
                ci = new CultureInfo("DESIRED CULTURE");
            }
        }

        public string Text { get; set; }

        public object ProvideValue(IServiceProvider serviceProvider)
        {
            string translation = string.Empty;

            if (Text != null)
            {
                ResourceManager manager = new ResourceManager(ResourceId, typeof(TranslateExtension).GetTypeInfo().Assembly);

                translation = manager.GetString(Text, ci) ?? Text;
            }

            return translation;
        }
    }
}

Every time a string is being obtained, a new ctor is being fired and the culture is being retrieved dynamically. You can change the CultureInfo inside the ctor here: ci = new CultureInfo("DESIRED CULTURE");

You can see an example using App properties here

Upvotes: 0

Related Questions