android - MvxListView 从代码中为模板布局创建绑定(bind)

标签 android xamarin.android mvvmcross

假设我有一个带有 MvxListView 的简单布局:

<?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/LiivControl.Client.Droid"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <Mvx.MvxListView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        local:MvxBind="ItemsSource AutoListItems; ItemClick AutoListItemClicked"
        local:MvxItemTemplate="@layout/vbmvxautoviewlistitem" />
</LinearLayout>

我的项目模板布局如下:

<?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/LiivControl.Client.Droid"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:paddingTop="10dip"
    android:paddingBottom="10dip"
    android:paddingLeft="15dip">
    <TextView
        android:id="@+id/list_complex_title"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceLarge" />
    <TextView
        android:id="@+id/list_complex_caption"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceSmall" />
</LinearLayout>

我想从代码隐藏中为我的 itemtemplate 中的两个 textview 元素指定绑定(bind)。我不确定如何最好地去做。我想我可以在 MvxListView 后面的 View 代码中做一些“OnViewModelSet”。我尝试了以下但显然不起作用,因为它找不到控件。

protected override void OnViewModelSet()
    {
        IVbMvxAutoListViewModel vm = base.ViewModel as IVbMvxAutoListViewModel;

        TextView title = this.FindViewById<TextView>(Resource.Id.list_complex_title);
        this.CreateBinding(title).For(x => x.Text).To(vm.ListItemDescriptor.TitlePropName).Apply();

        TextView subTitle = this.FindViewById<TextView>(Resource.Id.list_complex_caption);
        this.CreateBinding(subTitle).For(x => x.Text).To(vm.ListItemDescriptor.SubTitlePropName).Apply();
        base.OnViewModelSet();
    }

我的另一个想法是以某种方式拦截项目模板 View 的 oncreate,但如果我为项目模板布局创建 View 代码文件,则不会调用 OnCreate。

最佳答案

要在代码中进行绑定(bind),最好:

  1. 实现自定义MvxListViewItem
  2. 实现自定义 MvxAdapter 以返回自定义 ListView 项
  3. 实现自定义 MvxListView 以使用自定义 MvxAdapter

没有测试过,但是这方面的代码大概是这样的:

1。实现自定义 MvxListViewItem

public class CustomListItemView
    : MvxListItemView
{
    public MvxListItemView(Context context,
                           IMvxLayoutInflater layoutInflater,
                           object dataContext,
                           int templateId)
        : base(context, layoutInflater, dataContext, templateId)
    {
        var control = this.FindViewById<TextView>(Resource.Id.list_complex_title);
        var set = this.CreateBindingSet<CustomListViewItem, YourThing>();
        set.Bind(control).To(vm => vm.Title);
        set.Apply();
    }
}

2。创建自定义 MvxAdapter

在此覆盖 CreateBindableView

public class CustomAdapter
    : MvxAdapter
{
    public CustomAdapter(Context context)
        : base(context)
    {
    }

    protected override IMvxListItemView CreateBindableView(object dataContext, int templateId)
    {
        return new CustomListItemView(_context, _bindingContext.LayoutInflater, dataContext, templateId);
    }
}

原创:https://github.com/MvvmCross/MvvmCross/blob/v3.1/Cirrious/Cirrious.MvvmCross.Binding.Droid/Views/MvxAdapter.cs#L298

3。实现自定义 MvxListView 以使用适配器

这应该很简单:

public class CustomListView
    : MvxListView
{
    public CustomListView(Context context, IAttributeSet attrs)
        : base(context, attrs, new CustomAdapter(context))
    {
    }
}

只要它在您的主 UI 程序集中,它就应该可以在您的 axml 中使用:

<CustomListView 
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    local:MvxBind="ItemsSource AutoListItems; ItemClick AutoListItemClicked"
    local:MvxItemTemplate="@layout/vbmvxautoviewlistitem" />

如果 CustomListView 不在您的主 UI 程序集中,那么有一些技巧可以让 MvvmCross 在您的 Setup 中选择它 - 请参阅 Providing Custom Android在 https://github.com/MvvmCross/MvvmCross/wiki/Customising-using-App-and-Setup#wiki-providing-custom-views-android 中查看程序集


以上是执行此操作的最佳方法 (IMO) - 但如果您愿意,则只需在自定义适配器中应用绑定(bind)并在 OnCreate< 中设置该适配器,即可用更少的代码完成此操作 在你的 Activity

关于android - MvxListView 从代码中为模板布局创建绑定(bind),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21515976/

相关文章:

android - ListView 不在 App Widget 中显示数据

android - 抽屉导航中的图像应该有多大?

c# - MVVX无法从MvxDefaultViewModelLocator初始化ViewModel

ios - 关闭 View 时如何传回数据

xamarin - 将 Xamarin.Forms 与 native 页面结合使用(Xamarin.iOS、UWP)

android - adb 套接字不工作和守护进程

android - 如何在可扩展 ListView 中插入标题行

xamarin.android - 无法将Xamarin.Android中的NuGet包Xamarin.Forms更新为v2.5

c# - 如何将我的 Monodroid 应用程序安装到我的 HTC 设备?

android - System.InvalidCastException : Specified cast is not valid on editText. AddTextChangedListener