我有一个在.NET标准库(核心项目)MvvmCross 6.1.2和RESX资源Xamarin.Android项目。
TL;博士:我想改变应用程序设置语言,无需重新启动应用程序。目前的做法需要重新启动应用程序或导致应用程序崩溃是由于几个开关后高的内存使用情况。
到现在我一直在使用这是通过改变在AppLanguageService
语言定制CultureInfo
。
private void ChangeLocally(string code)
{
Settings.ApplicationLanguage = code;
Strings.Culture = new CultureInfo(code);
CultureInfo.DefaultThreadCurrentUICulture = Strings.Culture;
((MvxResxTextProvider) textProvider).CurrentLanguage = Strings.Culture;
}
在我的Android的布局我用MvxLang
结合展现译名。为了改变语言在Android上我也在我的Recreate()
调用BaseActivity
。然而,这是造成某种性能问题。夫妇这样的语言的切换后的应用程序是unusably缓慢,坠毁由于高内存消耗。看来,视图模型和视图正在重建,但旧的视图模型被保存在后台。
我也试图与在strings.xml
目录中相应的语言环境values
文件的正式的办法,但只有后两种调用Recreate()
或重新启动应用程序的语言的变化是明显的。
于是我放弃了Recreate()
方法,而是试图只刷新语言变更后的Android的看法。不幸的是这已经涉及到几个问题:
local:MvxBind="Text Language(TextSource, 'translated_term')"
更新(MvxLang
是OneTime
只)RaiseAllPropertiesChanged()
在BaseViewModel
现在只有重新启动应用程序允许使用的应用程序在不同的语言。
我希望能够在不重新启动应用程序更新的Android观点或我想用Recreate()
呼叫而不泛滥的内存(即或者处置旧的视图和视图模型或重复使用它们)。有没有实现任何适当的方式?
你需要做的的就是调用RaiseAllPropertiesChanged
上仍然活着的ViewModels。下面是做到这一点的一种方法:
创建时ChangeLocally在你AppLanguageService调用,将要播出的消息:
public class CultureChangedMessage : MvxMessage
{
public CultureInfo CultureInfo { get; private set; }
public CultureChangedMessage(object sender, CultureInfo cultureInfo) : base(sender)
{
CultureInfo = cultureInfo;
}
}
订阅在BaseViewModel此消息:
public class BaseViewModel : MvxViewModel
{
private readonly MvxSubscriptionToken _cultureChangedToken;
public BaseViewModel(IMvxMessenger messenger)
{
_cultureChangedToken = messenger.Subscribe<CultureChangedMessage>(OnCultureChanged);
}
private async void OnCultureChanged(CultureChangedMessage cultureChangedMessage)
{
await RaiseAllPropertiesChanged();
}
...
}
发布消息的每个文化在AppLanguageService改变时间:
private void ChangeLocally(string code)
{
Settings.ApplicationLanguage = code;
Strings.Culture = new CultureInfo(code);
CultureInfo.DefaultThreadCurrentUICulture = Strings.Culture;
((MvxResxTextProvider) textProvider).CurrentLanguage = Strings.Culture;
//let all ViewModels that are active know the culture changed
Mvx.IoCProvider.Resolve<IMvxMessenger>().Publish<CultureChangedMessage>(new CultureChangedMessage(new CultureInfo(code)));
}