Search code examples
androidxamarinmvvmcross

Can't find MvxListItemView constructor


I am new to Xamarin, but need to create an Android app, so it is time to learn.

I heard about MvvmCross, and thought it would be a good addition, as it seems to simplify things a little.

I created a basic app, got a text box to show, that sort of thing.

I then tried adding a list view, using the Dilbert example.

When I try and run a view with the MvxListItemView

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

I get this error.

System.NotSupportedException: Unable to find a constructor with signature (Android.Content.Context, Android.Util.IAttributeSet) on type MvvmCross.Binding.Droid.Views.MvxListItemView. Please provide the missing constructor.

From what I can see the constructor is

public MvxListItemView(Context context, IMvxLayoutInflaterHolder layoutInflaterHolder, object dataContext, int templateId);

I cannot find any obvious differences in mine, and the demo.

Is there something I am missing, or maybe overlooked?

ProcessFormView.axml:

<?xml version="1.0" encoding="utf-8"?>
<Mvx.MvxListView 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"
             local:MvxBind="ItemsSource Form"
             local:MvxItemTemplate="@layout/FormItem" />

FormItem.axml

<?xml version="1.0" encoding="utf-8"?>
<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">
    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:textSize="40dp"
        android:text="Form Item" />
    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:textSize="40dp"
        local:MvxBind="Text Field" />
</LinearLayout>

Solution

  • It seems to me as though Android can't find the MvxListItemView contructor it's looking for because it's searching the wrong assemblies. You're using Mvx.MvxListView in your layout, but that's a shortcut that requires you registering the namespace abbreviation in your Setup class. There are three ways of fixing the problem:

    Option 1: AndroidViewAssemblies

    Change Mvx.MvxListView in your layout to MvxListView. Then, you need to provide Android with the assembly in which to find MvxListView, which is done with the AndroidViewAssemblies override in Setup:

    protected override IEnumerable<Assembly> AndroidViewAssemblies 
        => new List<Assembly>(base.AndroidViewAssemblies)
    {
        typeof(MvvmCross.Binding.Droid.Views.MvxListView).Assembly,
        typeof(MvvmCross.Binding.Droid.Views.MvxListItemView).Assembly
    };
    

    This is the cleaner option, and the one I'd personally go with. Note that you'd need to follow the same two steps for every Mvx control in your app: removing the namespace from the layout, and registering it's assembly.

    Option 2: ViewNamespaceAbbreviations

    This option tells Android that Mvx.MvxListView actually means MvvmCross.Binding.Droid.Views.MvxListItemView, and is also achieved with an override in Setup:

    protected override IDictionary<string, string> ViewNamespaceAbbreviations
        => new Dictionary<string, string>
    {
        {
            "Mvx", "MvvmCross.Binding.Droid.Views"
        }
    };
    

    If you decide on option 2, be sure to leave your layouts unchanged (i.e. still use Mvx.MvxListView).

    Option 3: Laziness

    The easiest way to fix the issue is to fully qualify the namespace in your layout, by changing Mvx.MvxListView to MvvmCross.Binding.Droid.Views.MvxListView. The downside here is that you'd need to fully qualify every MvvmCross control you use, which is awkward and messy.