Xamarin表单使用Android资源更改语言

问题描述

根据该主题的答案 Change Language for Xamarin Android App using Resources 我使用此代码在应用运行时更改了语言。

onMeasure

它可以正常工作。除了由于某种原因我还没有找到的时候,否则不会! 我的应用程序运行时,语言环境改回原始语言环境。我还不能复制它...有什么想法吗?

谢谢。

解决方法

如果您使用了xamarin形式,则可以使用Xamarin.Forms String and Image Localization来实现。

例如。我添加了Change Button英语和日语的本地化版本。

enter image description here

enter image description here

然后我在xaml中使用了

 <StackLayout>
       
        <Label Text="{x:Static resources:AppResources.NotesLabel}"
               WidthRequest="300"
               HorizontalOptions="CenterAndExpand"
               VerticalOptions="Start"/>
        <Entry Placeholder="{x:Static resources:AppResources.NotesPlaceholder}"
               WidthRequest="300"
               HorizontalOptions="CenterAndExpand"
               VerticalOptions="Start"/>
        <Button Text="{x:Static resources:AppResources.AddButton}"
                WidthRequest="300"
                HorizontalOptions="CenterAndExpand"
                VerticalOptions="Start"/>
        <Button Text="{x:Static resources:AppResources.ChangeButton}" Clicked="Button_Clicked"></Button>
    </StackLayout>

当我单击按钮时,我将更改语言并刷新此页面。

  public partial class LocalizedXamlPage : ContentPage
    {
        public LocalizedXamlPage()
        {
            InitializeComponent();
        }

        private void Button_Clicked(object sender,System.EventArgs e)
        {
        
            CultureInfo.CurrentUICulture = new CultureInfo("ja-JP",false);
            App.Current.MainPage =new NavigationPage( new LocalizedXamlPage());
           
        }
    }

此处正在运行GIF(我无法重现您的问题,如果您在运行时更改文本,请刷新视图)。

enter image description here

这是我的演示。

https://github.com/851265601/LocalzationDemo

================ 更新 ========================

。我想更改语言环境,以便键盘,日期选择器和时间选择器与应用程序的语言环境匹配,而不与设备的语言环境匹配。例如,我的设备语言是英语,而我的应用程序语言是希腊语。因此,我希望数字键盘的小数点是逗号而不是点,并且我希望日期选择器中的“确定”和“取消”按钮使用希腊语。

您是否想获得遵循GIF的结果?

enter image description here

如果是这样,您可以创建一个BaseActivity.csLanguageManager

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

然后使用MainActivity扩展BaseActivity,并在public static MainActivity instance;中添加MainActivity

    [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());
        }
    }

在您的depdenceService中,使用以下代码对其进行更改并重新启动应用程序。

[assembly: Dependency(typeof(ChangeLanguageService))]
namespace UsingResxLocalization.Droid
{
    public class ChangeLanguageService : IChangeService
    {
        public void ChangeIanguage(string lang)
        {
           
            LanguageManager.ChangeLanguage(MainActivity.instance,"en");
            //restart your application.
            Intent intent = new Intent(MainActivity.instance,typeof(MainActivity));
            intent.SetFlags(ActivityFlags.ClearTask | ActivityFlags.NewTask);
            MainActivity.instance.StartActivity(intent);
        }
    }
}