Xamarin 表单中的 Android 图像本地化 [英] Android image localisation in Xamarin Form
问题描述
我有一个 Xamarin Form 应用程序,它有一个语言下拉菜单,因此用户可以选择应用程序语言.当用户选择我调用的语言时:
CultureInfoculture = CultureInfo.CreateSpecificCulture(language);System.Globalization.CultureInfo.CurrentUICulture = 文化;Thread.CurrentThread.CurrentCulture = 文化;Thread.CurrentThread.CurrentUICulture = 文化;AppResources.Culture = 文化;
应用程序运行良好并从 AppResources.{language}.resx 中选取字符串我的问题是本地化图像时.根据 Microsoft 的建议,我已将我的图像添加到 android 项目内的 Resources/drawable 文件夹中.就我而言,我将Thanks.jpg 添加到Resources/drawable 和Resources/drawable-fr.但即使我选择 fr-FR 作为语言,它也只显示 Resources/drawable 文件夹上的图像,但是我发现如果不是更改应用程序语言(文化),而是更改设备语言,设备显示正确的图像(资源/drawable-fr 中的图像).我想知道是否有办法解决这个问题.
您可以创建一个依赖服务来修复它.
首先,创建一个接口.
公共接口 IChangeService{void ChangeIanguage(string lang);}
我们在 xamarin 表单的 this 格式代码中使用了它.
<TimePicker></TimePicker><图像宽度请求=100"><图片来源><OnPlatform x:TypeArguments=ImageSource"><On Platform=iOS、Android"值=flag.png"/><在平台上=UWP"值=资产/图像/flag.png";/></OnPlatform></Image.Source></图片><按钮文本=更改"Clicked=Button_Clicked"></Button></StackLayout>
这是后台代码.
公共部分类 LocalizedXamlPage : ContentPage{公共 LocalizedXamlPage(){初始化组件();}私有无效Button_Clicked(对象发送者,System.EventArgs e){DependencyService.Get().ChangeIanguage(en");}}
然后在android平台实现接口.如果我们更改本地化,我们需要它在运行时工作,我们应该重新启动我们的应用程序.
[程序集:依赖(typeof(ChangeLanguageService))]命名空间 UsingResxLocalization.Droid{公共类 ChangeLanguageService : IChangeService{public void ChangeIanguage(string lang = "in"){LanguageManager.ChangeLanguage(MainActivity.instance, lang);//重新启动您的应用程序.Intent intent = new Intent(MainActivity.instance, typeof(MainActivity));intent.SetFlags(ActivityFlags.ClearTask | ActivityFlags.NewTask);MainActivity.instance.StartActivity(intent);}}}
然后我们需要创建一个BaseActivity
(因为我们在android中改变了Locale
,所以我们应该使用相同的Context.)和LanguageManager
(在运行时更改本地化)
使用系统;使用 System.Collections.Generic;使用 System.Linq;使用 System.Text;使用 Android.App;使用 Android.Content;使用Android.OS;使用 Android.Runtime;使用 Android.Support.V7.App;使用 Android.Views;使用 Android.Widget;使用 Java.Util;使用 Xamarin.Forms.Platform.Android;命名空间 UsingResxLocalization.Droid{公共类 BaseActivity : FormsAppCompatActivity{protected override void AttachBaseContext(Context @base){base.AttachBaseContext(LanguageManager.LoadLanguage(@base));}}公共类语言管理器{private const string MYLANGUAGE = "myLanguage";私有常量字符串 MYPREF = "myPreference";公共静态上下文加载语言(上下文上下文){var loadedLanguage = GetLanguage(context, Locale.Default.Language);返回 ChangeLanguage(context,loadedLanguage);}public static Context ChangeLanguage(上下文上下文,字符串语言){SaveLanguage(上下文,语言);if (Build.VERSION.SdkInt >= BuildVersionCodes.N){返回 ChangeForAPI24(上下文,语言);}返回 ChangeForLegacy(上下文,语言);}私有静态字符串 GetLanguage(上下文上下文,字符串语言){var privatePreference = context.GetSharedPreferences(MYPREF, FileCreationMode.Private);返回 privatePreference.GetString(MYLANGUAGE, Language);}private static void SaveLanguage(上下文上下文,字符串语言){var privatePreference = context.GetSharedPreferences(MYPREF, FileCreationMode.Private);var editor = privatePreference.Edit();editor.PutString(MYLANGUAGE, 语言);editor.Apply();}私有静态上下文 ChangeForAPI24(上下文上下文,字符串语言){//对于 api >= 24var locale = new Locale(language);Locale.Default = locale;var configuration = context.Resources.Configuration;configuration.SetLocale(locale);configuration.SetLayoutDirection(locale);返回 context.CreateConfigurationContext(configuration);}私有静态上下文 ChangeForLegacy(上下文上下文,字符串语言){var locale = new Locale(language);Locale.Default = locale;var 资源 = context.Resources;var 配置 = 资源.配置;configuration.Locale = locale;resources.UpdateConfiguration(配置,resources.DisplayMetrics);返回上下文;}}}
为了使 mainAcitvity 扩展 BaseActivity.cs
.并公开公共静态MainActivity实例;
,
[Activity(Label = "UsingResxLocalization", Icon = "@mipmap/icon", Theme = "@style/MainTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]公共类 MainActivity : BaseActivity{公共静态 MainActivity 实例;protected override void OnCreate(Bundle savedInstanceState){TabLayoutResource = Resource.Layout.Tabbar;ToolbarResource = Resource.Layout.Toolbar;实例=这个;base.OnCreate(savedInstanceState);global::Xamarin.Forms.Forms.Init(this, savedInstanceState);加载应用程序(新应用程序());}}
这是正在运行的 GIF.
========更新==========
当设备语言为英语时,我通过将语言更改为 fr 来使用法国国旗进行测试.
我把我的演示上传给你,你可以测试一下.
I have a Xamarin Form application which has a language dropdown so user can select the application language. When user select a language I call:
CultureInfo culture = CultureInfo.CreateSpecificCulture(language);
System.Globalization.CultureInfo.CurrentUICulture = culture;
Thread.CurrentThread.CurrentCulture = culture;
Thread.CurrentThread.CurrentUICulture = culture;
AppResources.Culture = culture;
The application works fine and picks the strings from AppResources.{language}.resx My problem is when localising an image. As per Microsoft's suggestion I have added my image to Resources/drawable folders inside the android project. In my case, I added thanks.jpg to Resources/drawable and Resources/drawable-fr. But it only shows the image on Resources/drawable folder even when I select fr-FR as language, however I found out if instead of changing the application language(culture), I change the device language, the device show the correct image(the image inside Resources/drawable-fr). I was wondering if there is any way to fix this issue.
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.
这篇关于Xamarin 表单中的 Android 图像本地化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!