You can create a dependence service to fix it.
First of all, create a interface.
public interface IChangeService
{
void ChangeIanguage(string lang);
}
We used it in the this format code in the xamarin forms.
<StackLayout>
<TimePicker></TimePicker>
<Image WidthRequest="100">
<Image.Source>
<OnPlatform x:TypeArguments="ImageSource">
<On Platform="iOS, Android" Value="flag.png" />
<On Platform="UWP" Value="Assets/Images/flag.png" />
</OnPlatform>
</Image.Source>
</Image>
<Button Text="Change" Clicked="Button_Clicked"></Button>
</StackLayout>
Here is background code.
public partial class LocalizedXamlPage : ContentPage
{
public LocalizedXamlPage()
{
InitializeComponent();
}
private void Button_Clicked(object sender, System.EventArgs e)
{
DependencyService.Get<IChangeService>().ChangeIanguage("en");
}
}
Then achieve the interface in the android platform. If we change the localization, we need it to work at the runtime, we should restart our application.
[assembly: Dependency(typeof(ChangeLanguageService))]
namespace UsingResxLocalization.Droid
{
public class ChangeLanguageService : IChangeService
{
public void ChangeIanguage(string lang = "in")
{
LanguageManager.ChangeLanguage(MainActivity.instance, lang);
//restart your application.
Intent intent = new Intent(MainActivity.instance, typeof(MainActivity));
intent.SetFlags(ActivityFlags.ClearTask | ActivityFlags.NewTask);
MainActivity.instance.StartActivity(intent);
}
}
}
Then we need to create a BaseActivity
(because we change the Locale
in android, we should use the same Context.) and LanguageManager
(change the localization at the runtime)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Support.V7.App;
using Android.Views;
using Android.Widget;
using Java.Util;
using Xamarin.Forms.Platform.Android;
namespace UsingResxLocalization.Droid
{
public class BaseActivity : FormsAppCompatActivity
{
protected override void AttachBaseContext(Context @base)
{
base.AttachBaseContext(LanguageManager.LoadLanguage(@base));
}
}
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
var 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;
}
}
}
To make the mainAcitvity extend the BaseActivity.cs
. And expose the public static MainActivity instance;
,
[Activity(Label = "UsingResxLocalization", Icon = "@mipmap/icon", Theme = "@style/MainTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
public class MainActivity : BaseActivity
{
public static MainActivity instance;
protected override void OnCreate(Bundle savedInstanceState)
{
TabLayoutResource = Resource.Layout.Tabbar;
ToolbarResource = Resource.Layout.Toolbar;
instance = this;
base.OnCreate(savedInstanceState);
global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
LoadApplication(new App());
}
}
Here is runinng GIF.
========Update=========
I make a test with France flag by changing language to fr when the device language is English.
I upload my demo to you, you can test it.
https://github.com/851265601/LocalzationDemo/blob/master/LocalzationDemoWithFlag.zip
If you want to change the text of Button or other label, when you click the Button, Please add CultureInfo.CurrentUICulture = new CultureInfo("fr", false);
as well in the click event. You can see this GIF.