在MvvmCross 3.5.1中实现Fragments的正确方法是什么?

4

在将我的Xamarin.Android项目从3.5升级到3.5.1后,我遇到了膨胀碎片错误。

Unable to start activity ComponentInfo{xxx.xxx/md51537e9497dba76724980c8d1dff85301.MyView}: android.view.InflateException: Binary XML file line #1: Error inflating class fragment


Caused by: android.app.Fragment$InstantiationException: Trying to instantiate a class md51537e9497dba76724980c8d1dff85301.LoginView that is not a Fragment

这个错误是什么原因导致的?3.5.1 版本中有没有破坏性变化?

我的 Fragment 的定义如下:

public class LoginFormView : MvxFragment
    {
        public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
        {
            var ignore = base.OnCreateView(inflater, container, savedInstanceState);
        return this.BindingInflate(Resource.Layout.LoginFormView, null);
    }
}

我已经通过Xamarin组件商店包含了V4支持。

我通过以下方式膨胀我的片段:

public class LoginView : BaseMvxFragmentActivity
    {
...

    protected override void OnCreate(Bundle bundle)
    {
        base.OnCreate(bundle);
        SetContentView(Resource.Layout.LoginView);

        _loginForm = (LoginFormView)SupportFragmentManager.FindFragmentById(Resource.Id.sub_login_form);
        _loginForm.ViewModel = MyViewModel.LoginFormViewModel;
    }
    ...
 }

更新 1

我的 axml 布局如下:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:local="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#FFFFFF">
<!-- Snip -->
<LinearLayout
    android:id="@+id/InnerRelativeLayout"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:animateLayoutChanges="true"
    android:padding="10dp">
    <fragment
        class="com.namespace.LoginFormView"
        android:id="@+id/sub_login_form"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        local:MvxBind="Visibility ShowLoginFormViewModel,Converter=Visibility" />

更新2

当我构建到物理设备时,它能够正常工作。

更新3

如果按照CheeseBaron的建议添加[Register],则原因会改变为:

[MonoDroid] Caused by: android.app.Fragment$InstantiationException: Trying to instantiate a class com.namespace.Droid.Views.LoginFormView that is not a Fragment

更多信息:

[MonoDroid] UNHANDLED EXCEPTION:
[MonoDroid] Android.Views.InflateException: Exception of type 'Android.Views.InflateException' was thrown.
[MonoDroid] at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () <IL 0x00011, 0x0004b>
[MonoDroid] at Android.Runtime.JNIEnv.CallObjectMethod (intptr,intptr,Android.Runtime.JValue*) [0x00064] in /Users/builder/data/lanes/monodroid-mavericks-monodroid-5.1-series/d23da369/source/monodroid/src/Mono.Android/src/Runtime/JNIEnv.g.cs:195
[MonoDroid] at Android.Views.LayoutInflater.Inflate (int,Android.Views.ViewGroup,bool) [0x00082] in /Users/builder/data/lanes/monodroid-mavericks-monodroid-5.1-series/d23da369/source/monodroid/src/Mono.Android/platforms/android-16/src/generated/Android.Views.LayoutInflater.cs:687
[MonoDroid] at Cirrious.MvvmCross.Binding.Droid.BindingContext.MvxAndroidBindingContext.CommonInflate (int,Android.Views.ViewGroup,Cirrious.MvvmCross.Binding.Droid.Binders.IMvxLayoutInfactorFactory,bool) <IL 0x00030, 0x00136>
[MonoDroid] at Cirrious.MvvmCross.Binding.Droid.BindingContext.MvxAndroidBindingContext.BindingInflate (int,Android.Views.ViewGroup,bool) <IL 0x00015, 0x000a5>
[MonoDroid] at Cirrious.MvvmCross.Binding.Droid.BindingContext.MvxAndroidBindingContext.BindingInflate (int,Android.Views.ViewGroup) <IL 0x00004, 0x00044>
[MonoDroid] at Cirrious.MvvmCross.Binding.Droid.BindingContext.MvxBindingContextOwnerExtensions.BindingInflate (Cirrious.MvvmCross.Binding.BindingContext.IMvxBindingContextOwner,int,Android.Views.ViewGroup) <IL 0x0000f, 0x000f5>
[MonoDroid] at Cirrious.MvvmCross.Droid.Fragging.MvxFragmentActivity.SetContentView (int) <IL 0x00003, 0x00037>
[MonoDroid] at com.namespace.Droid.Views.LoginView.OnCreate (Android.OS.Bundle) [0x0000e] in /xxx/Ccom.namespace.Droid/Views/LoginView.cs:34
[MonoDroid] at Android.App.Activity.n_OnCreate_Landroid_os_Bundle_ (intptr,intptr,intptr) [0x00011] in /Users/builder/data/lanes/monodroid-mavericks-monodroid-5.1-series/d23da369/source/monodroid/src/Mono.Android/platforms/android-16/src/generated/Android.App.Activity.cs:2374
[MonoDroid] at (wrapper dynamic-method) object.facfe989-fd2b-40d3-bf63-959b844af987 (intptr,intptr,intptr) <IL 0x00017, 0x0002b>

1
Android 3.5.1版本的膨胀机制发生了变化,这是为了解决Xam Android支持包的更改所引起的。发布说明请参见http://slodge.blogspot.co.uk/。我怀疑你引用的膨胀信息并不是来自MvvmCross...所以我的直觉告诉我,它更可能与Xam的变化有关,而不是Mvx的差异。当然,@cheesebaron建议添加`[Register]`,然后进行清理和重建,感觉会有所帮助。 - Stuart
谢谢,但是我已经添加了[Register]并进行了一次清理/重建,但仍然出现相同的错误。 - Chris Koiak
1
如果您仍然收到相同的错误 - 即关于md51537e9497dba76724980c8d1dff85301的错误,则意味着“注册”未正常工作。 - Stuart
你说得对,消息已经改变了(我错过了它),现在包括完整的命名空间。我添加了“更新3”。我在想是否应该使用FullFragging? - Chris Koiak
1个回答

3
Xamarin.Android 5.1引入了一些破坏性的变化。这意味着您需要在所有碎片中添加[Register("app.namespace.FragmentName")]。更多信息请参见:https://github.com/MvvmCross/MvvmCross/issues/987http://forums.xamarin.com/discussion/37277/stable-release-xamarin-android-5-1-0-breaking-changes-new-features-and-bug-fixes
编辑:好的!这与#990无关。问题是由于某种原因,MvxFragment不能被充气,因为它未被识别为一个Fragment。当更改为最小目标15和FullFragging MvvmCross nuget后,它开始工作。还要记住,所有Java命名空间都需要小写。因此,当您使用[Register]时,必须符合此规定。您的示例还有两个MainLauncher活动,所以我不得不删除默认的MainActivity。您的FirstViewFragment还定义了一个Activity,为什么要这样做?所以我进行的更改简述如下:
  • 最低目标15
  • 将Fragging替换为FullFragging
  • FirstViewFragment中删除[Activity]标志
  • FirstViewFragment[Register]的命名空间小写
  • FirstViewMvxFragmentActivity更改为MvxActivity
  • 删除MainActivity
  • SupportFragmentManager替换为FragmentManager
  • FirstView.axmlclass的命名空间小写
然后它就可以工作了。为什么MvvmCross中的片段支持版本不起作用需要进行调查。

不幸的是,将属性添加到LoginFormView并不能解决问题。 - Chris Koiak
好的,可能与 https://github.com/MvvmCross/MvvmCross/issues/990 相关。你能否制作一个小的重现样本? - Cheesebaron
可在以下链接中获取重现示例:https://www.dropbox.com/s/v8l4fworjgtrdxy/FragmentTest.zip?dl=0 - Chris Koiak
1
我不确定我理解你的意思,什么没有起作用?名称应该是大写的,但命名空间应该是小写的。因此,类似于:com.abc.MyFragment - Cheesebaron
3
@Cheesebaron,那么我们无法更改的碎片怎么办?例如Google Maps中命名为com.google.android.gms.maps.SupportMapFragment的碎片。 - Nikola
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接