简体   繁体   English

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

[英]What's the proper way to implement Fragments in MvvmCross 3.5.1

After upgrading from 3.5 to 3.5.1 I am getting errors inflating Fragments in my Xamarin.Android project. 从3.5升级到3.5.1后,我在Xamarin.Android项目中出现错误,导致碎片膨胀。

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

What is causing this error? 导致此错误的原因是什么? Are there breaking changes in 3.5.1? 3.5.1中是否有重大变化?

My Fragment is defined as 我的片段被定义为

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

I have included the V4 support via the Xamarin Component store. 我通过Xamarin Component商店包含了V4支持。

I inflate my fragment via: 我通过以下方式膨胀我的片段:

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

Update 1 更新1

My axml layout is as follows 我的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" />

Update 2 更新2

It works fine when I build to a physical device 当我构建到物理设备时,它工作正常

Update 3 更新3

If I add [Register] as per CheeseBaron's suggestion then the cause changes to: 如果按照CheeseBaron的建议添加[Register] ,原因将变为:

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

More info: 更多信息:

[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>

Xamarin.Android 5.1 introduces some breaking changes. Xamarin.Android 5.1引入了一些重大变化。 This means you need to add [Register("app.namespace.FragmentName")] in all your Fragments. 这意味着您需要在所有片段中添加[Register("app.namespace.FragmentName")]

For more information see: https://github.com/MvvmCross/MvvmCross/issues/987 http://forums.xamarin.com/discussion/37277/stable-release-xamarin-android-5-1-0-breaking-changes-new-features-and-bug-fixes 有关详细信息,请参阅: https//github.com/MvvmCross/MvvmCross/issues/987 http://forums.xamarin.com/discussion/37277/stable-release-xamarin-android-5-1-0-breaking-变化,新特点,和错误修复

EDIT: 编辑:

OK! 好! This is not related to #990. 这与#990无关。 The problem is that for some reason the MvxFragment cannot be inflated as it is not recognized as a Fragment. 问题是由于某种原因, MvxFragment不能被夸大,因为它不被识别为片段。 When changing to minimum target 15 and the FullFragging MvvmCross nuget instead it starts to work. 当改为最小目标15和FullFragging MvvmCross nuget时,它开始工作。

Also remember, that all Java namespaces need to be lowercase. 还要记住, 所有 Java命名空间都需要小写。 So when you use [Register] you must conform to that. 因此,当您使用[Register]您必须遵守该[Register]

Your sample is also having two MainLauncher Activities, so I had to remove the default MainActivity . 您的示例还有两个MainLauncher活动,因此我必须删除默认的MainActivity Your FirstViewFragment also defines an Activity , why does it do that??? 你的FirstViewFragment还定义了一个Activity ,它为什么这样做???

So changes in short I made: 所以我做的改变很简短:

  • Minimum target 15 最低目标15
  • Replace Fragging with FullFragging 用FullFragging替换Fragging
  • Remove [Activity] flags from FirstViewFragment FirstViewFragment删除[Activity]标志
  • Lowercase namespace in [Register] in FirstViewFragment FirstViewFragment[Register]中的小写命名空间
  • Change FirstView from MvxFragmentActivity to MvxActivity FirstViewMvxFragmentActivity更改为MvxActivity
  • Remove MainActivity 删除MainActivity
  • Replace SupportFragmentManager with FragmentManager FragmentManager替换SupportFragmentManager
  • Lowercase namespace in class in FirstView.axml FirstView.axmlclass小写命名空间

Then it works. 然后它工作。 Why the support version of framents in MvvmCross does not work needs to be investigated. 为什么MvvmCross中的支持版本的框架不起作用需要进行调查。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM