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