Xamarin.Android/MvvmCross切后台改语言后崩溃异常解决
首先明确这个异常的含义:
System.InvalidOperationException: Your fragment is not generic and it does not have MvxFragmentPresentationAttribute attribute set!
这是MvvmCross的Fragment导航机制做校验时抛出的错误——MvvmCross需要明确知道你的Fragment对应的ViewModel类型,才能完成数据绑定、生命周期关联等核心功能。它提供了两种方式让你指定这个关联关系:要么让Fragment继承泛型版本的MvxFragment<TViewModel>,要么给Fragment类加上MvxFragmentPresentationAttribute标记。而当你切换系统语言后返回应用,Android会销毁并重新创建Activity和Fragment,这时候MvvmCross会重新执行Fragment的初始化校验,你的Fragment没满足上述两个条件中的任何一个,就触发了崩溃。
接下来是具体的修复方法,二选一即可:
方法一:使用泛型Fragment
把你的Fragment类改成继承泛型版本的MvxFragment,指定对应的ViewModel类型。比如:
// 原来的写法 // public class YourFragment : MvxFragment // 修改后的写法 public class YourFragment : MvxFragment<YourTargetViewModel> { // 你的Fragment原有代码 }
这样MvvmCross就能自动识别到Fragment对应的ViewModel,不需要额外的属性标记。
方法二:添加MvxFragmentPresentationAttribute标记
如果因为某些原因不想使用泛型Fragment,可以在你的Fragment类上添加这个属性,明确指定关联的ViewModel以及宿主容器信息。示例代码:
[MvxFragmentPresentation(typeof(HostViewModel), Resource.Id.your_content_container_id, true)] public class YourFragment : MvxFragment { // 你的Fragment原有代码 }
参数说明:
- 第一个参数:指定当前Fragment所属的宿主ViewModel类型(比如承载这个Fragment的Activity对应的ViewModel)
- 第二个参数:指定Fragment要嵌入的布局容器ID(比如Activity布局里的FrameLayout的ID)
- 第三个参数:布尔值,设置是否将这个Fragment添加到回退栈,根据你的导航需求调整即可
两种方法都能让MvvmCross在Fragment重建时通过校验,解决切换语言后返回崩溃的问题。
内容的提问来源于stack exchange,提问作者Rom

