【问题标题】:What's the proper way to implement Fragments in MvvmCross 3.5.1在 MvvmCross 3.5.1 中实现片段的正确方法是什么
【发布时间】:2015-05-04 13:55:26
【问题描述】:

从 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

是什么导致了这个错误? 3.5.1 中是否有重大更改?

我的片段被定义为

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>

【问题讨论】:

  • Android 通货膨胀在 3.5.1 中发生了变化 - 导致解决 Xam Android 支持包更改 - 发行说明是 slodge.blogspot.co.uk。我怀疑你引用的通货膨胀信息不是来自 MvvmCross ......所以我的直觉告诉我这更有可能与 Xam 变化有关,而不是与 Mvx 差异有关。当然@cheesebaron 的建议是添加[Register],然后清理和重建感觉可能会有所帮助。
  • 谢谢,但我已经添加了 [Register] 并执行了清理/重建,但仍然出现相同的错误。
  • 如果您仍然遇到相同的错误 - 即关于 md51537e9497dba76724980c8d1dff85301`,那么这意味着 Register 不起作用。
  • 你说得对,消息已更改(我错过了),现在包含完整的命名空间。我添加了“更新 3”。我想知道我是否应该使用 FullFragging?

标签: android android-fragments xamarin xamarin.android mvvmcross


【解决方案1】:

Xamarin.Android 5.1 引入了一些重大更改。这意味着您需要在所有片段中添加[Register("app.namespace.FragmentName")]

有关详细信息,请参阅: 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

编辑:

好的!这与#990 无关。问题是由于某种原因,MvxFragment 不能被夸大,因为它不被识别为片段。当更改为最小目标 15 和 FullFragging MvvmCross nuget 时,它开始工作。

还要记住,all Java 命名空间必须是小写的。所以当你使用[Register]时,你必须遵守那个。

您的示例也有两个MainLauncher 活动,所以我不得不删除默认的MainActivity。你的FirstViewFragment 还定义了一个Activity,为什么会这样???

所以我做了简短的更改:

  • 最低目标 15
  • 用 FullFragging 替换 Fragging
  • FirstViewFragment 中删除[Activity] 标志
  • [Register] 中的小写命名空间FirstViewFragment
  • FirstViewMvxFragmentActivity 更改为 MvxActivity
  • 删除MainActivity
  • SupportFragmentManager 替换为FragmentManager
  • class 中的小写命名空间FirstView.axml

然后就可以了。为什么MvvmCross中framents的支持版本不起作用需要调查。

【讨论】:

  • 不幸的是,将属性添加到 LoginFormView 并不能解决问题。
  • 好吧,可能和github.com/MvvmCross/MvvmCross/issues/990有关,你能不能做一个小的repro sample?
  • 不确定我理解你的意思,是什么不起作用?名称应为大写,但命名空间应为小写。比如:com.abc.MyFragment
  • @Cheesebaron 我们无法更改的片段呢?例如谷歌地图的片段名为com.google.android.gms.maps.SupportMapFragment
猜你喜欢
  • 2011-11-06
  • 2018-08-12
  • 1970-01-01
  • 2014-04-07
  • 1970-01-01
  • 2020-07-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多