如何使用MvvmCross流畅的API将RecyclerView项目的TextView绑定到Android上ViewModel的属性?

我在我的Xamarin Android项目中使用MvvmCross.我有一个MvxActivity与MvxRecyclerView,我已在其布局文件中分配了一个项目模板.
<MvxRecyclerView
    android:id="@+id/my_recycler_view"
    local:MvxItemTemplate="@layout/item_recycler_view" />

viewmodel非常简单,它只包含一个属性,用于保存要在RecyclerView中显示的数据:

public class Mainviewmodel : Mvxviewmodel
{
    private IEnumerable<viewmodelItem> _viewmodelItems;
    public IEnumerable<viewmodelItem> viewmodelItems
    {
        get { return _viewmodelItems; }
        set { SetProperty(ref _viewmodelItems,value); }
    }    
}

通常,我喜欢尽可能多地使用MvvmCross流畅的API,因为隐式重构支持.
所以在我的活动中,我绑定了MvxRecyclerView的属性,如下所示:

var recyclerView = View.FindViewById<MvxRecyclerView>(Resource.Id.my_recycler_view);
var set = this.CreateBindingSet<MainView,Mainviewmodel>();
set.Bind(recyclerView)
    .For(v => v.ItemsSource)
    .To(vm => vm.viewmodelItems);
set.Apply();

到现在为止还挺好.现在,项模板的布局文件基本上只包含一个TextView:

<LinearLayout>
    <TextView
        android:id="@+id/innerText" />
</LinearLayout>

我的viewmodelItem类看起来像这样:

public class viewmodelItem
{
    public string Title { get; set; }
}

我现在的问题是,如何以及在何处使用流畅的API将TextView.Text属性绑定到viewmodelItem.Title属性

我知道通过在项目模板布局文件中提供MvxBind属性,没有流畅的API很容易,但我真的更喜欢流畅的API解决方案.

解决方法

继承自MvxRecyclerAdapter并为RecyclerView创建自定义适配器.覆盖OnCreateViewHolder并返回自定义viewHolder.
public class MyAdapter : MvxRecyclerAdapter
{
    public MyAdapter(IMvxAndroidBindingContext bindingContext)
        : base(bindingContext)
    {
    }

    public override RecyclerView.ViewHolder OnCreateViewHolder(ViewGroup parent,int viewType)
    {
        var itembindingContext = new MvxAndroidBindingContext(parent.Context,this.BindingContext.LayoutInflaterHolder);
        var view = this.InflateViewForHolder(parent,viewType,itembindingContext);

        return new MyViewHolder(view,itembindingContext);
    }
}

在此ViewHolder中,您可以使用Fluent API进行绑定.

public class MyViewHolder : MvxRecyclerViewHolder
{
    private readonly TextView textView;

    public MyViewHolder(View itemView,IMvxAndroidBindingContext context)
        : base(itemView,context)
    {
        this.textView = itemView.FindViewById<TextView>(Android.Resource.Id.Text1);

        this.DelayBind(() =>
        {
            var set = this.CreateBindingSet<MyViewHolder,viewmodelItem>();
            set.Bind(this.textView).To(x => x.Title);
            set.Apply();
        });
    }
}

在您的Activity中创建适配器并将其添加到RecyclerView:

var adapter = new MyAdapter((IMvxAndroidBindingContext)this.BindingContext);
recyclerView.Adapter = adapter;

并将您的项目绑定到您的适配器的ItemsSource:

set.Bind(this.adapter).For(x => x.ItemsSource).To(x => x.viewmodelItems);

相关文章

Android性能优化——之控件的优化 前面讲了图像的优化,接下...
前言 上一篇已经讲了如何实现textView中粗字体效果,里面主要...
最近项目重构,涉及到了数据库和文件下载,发现GreenDao这个...
WebView加载页面的两种方式 一、加载网络页面 加载网络页面,...
给APP全局设置字体主要分为两个方面来介绍 一、给原生界面设...
前言 最近UI大牛出了一版新的效果图,按照IOS的效果做的,页...