【xamarin + MvvmCross 从零开始】三、MvvmCross 详解 (1)

前言

MvvmCross完全与Xamarin契合,也同样支持Android、iOS、WindowsPhone、WPF、WP8等多个平台,针对各个平台都有单独的实现。

在前面的例子中,我们已经使用了MvvmCross,使用MvvmCross实现了ViewModel和View的数据绑定。这次我们要对MvvmCross的一些常用对象通过实例的代码进行说明。

有兴趣的同学可以到MvvmCross的官方网站学习 https://mvvmcross.com/

目前MvvmCross的最新版本为4.4.0,我们就以这个版本为大家做下讲解。

MvvmCross类库说明

类库名称

说明

MvvmCross.Core

MvvmCross核心类库,实现核心对象、核心接口定义及实现。如MvxViewModel、MvxSetup等对象。

MvvmCross.Platform

MvvmCross平台类库,实现在公共的数据转换、Ioc、插件机制等。

MvvmCross.Binding

MvvmCross数据绑定实现程序集。实现通用的数据绑定,如Swiss、Tibet、Json、Fluent等多种数据绑定的解析。
MvvmCross.Localization MvvmCross本地化程序集。
MvvmCross.Ios 针对iOS平台的特定实现程序集,主要针对iOS平台的Controller、控件、对象进行封装。
MvvmCross.Droid 针对Android平台的特定实现程序集,主要针对Android平台的Activity、Fragment、控件、对象进行封装。

MvvmCross 常用对象

MvxApplication

MvxApplication做为MvvmCross的入口对象,必须声明在可移植应用程序集。也就是说是各个平台的实现都会依赖此对象。通常实现的方式为声明一个App对象,继承于MvxApplication。

image

Initialize方法,此方法必须进行重载,实现对应用程序的初始化。如在Ioc中注册服务对象和应用程序入口的ViewModel。

LoadPlugins方法,实现对插件的加载。

CreateDefaultViewModelLocator方法,通过重载此方法可实现自定义加载ViewModel。

典型的App实现是这样的:

using Acr.UserDialogs;
using MvvmCross.Core.ViewModels;
using MvvmCross.Platform;
using MvvmCross.Platform.IoC;
using XamarinSample.ViewModels;

namespace XamarinSample
{
    public class App : MvxApplication
    {
        public override void Initialize()
        {
            base.Initialize();

            // 注册所有的服务类
            CreatableTypes().EndingWith("Service").AsInterfaces().RegisterAsLazySingleton();
            Mvx.RegisterSingleton(UserDialogs.Instance);
            RegisterAppStart<MainViewModel>();
        }
    }
}

MvxSetup

MvvmCross是一个可灵活配置的框架,MvxSetup是所有配置信息的入口,可以通过重载方法的形式对MvvmCross进行配置。如替换Ioc控制、自定义加载第三方插件、增加自定义Convertion、自定义缓存等。

由于不同的平台有不同的特性,所以Setup会根据不同的平台有特定的实现,如在Android平台上默认实现为MvxAndroidSetup,在iOS平台上则为MvxIosSetup,当我们需要对MvvmCross进行配置时,只需要根据平台的不同继承不同的对象,再通过重载方法就可以实现灵活的自定义了。

image

典型的Setup定义是这样的:

using Android.Content;
using JRYC.Mobile.Common.Utilities;
using JRYC.Mobile.Droid.Extras;
using JRYC.Mobile.Droid.Impl;
using MvvmCross.Binding.Bindings.Target.Construction;
using MvvmCross.Core.ViewModels;
using MvvmCross.Droid.Platform;
using MvvmCross.Droid.Shared.Presenter;
using MvvmCross.Droid.Views;
using MvvmCross.Platform;
using MvvmCross.Platform.Converters;
using MvvmCross.Platform.IoC;

namespace JRYC.Mobile.Droid
{
    public class Setup : MvxAndroidSetup
    {
        public Setup(Context applicationContext) : base(applicationContext)
        {

        }
        protected override IMvxApplication CreateApp()
        {
            return new App();
        }

        /// <summary>
        /// Fill the Binding Factory Registry with bindings from the support library.
        /// </summary>
        protected override void FillTargetFactories(IMvxTargetBindingFactoryRegistry registry)
        {
            registry.RegisterCustomBindingFactory<CheckableLinearLayout>("Checked",
                x => new CheckableLinearLayout.CheckableLinearLayoutTargetBinding(x));
            registry.RegisterCustomBindingFactory<CheckableRelativeLayout>("Checked",
                x => new CheckableRelativeLayout.CheckableRelativeLayoutTargetBinding(x));
            base.FillTargetFactories(registry);
        }

        /// <summary>
        /// This is very important to override. The default view presenter does not know how to show fragments!
        /// </summary>
        protected override IMvxAndroidViewPresenter CreateViewPresenter()
        {
            var mvxFragmentsPresenter = new MvxFragmentsPresenter(AndroidViewAssemblies);
            Mvx.RegisterSingleton<IMvxAndroidViewPresenter>(mvxFragmentsPresenter);
            return mvxFragmentsPresenter;
        }

        protected override void FillValueConverters(IMvxValueConverterRegistry registry)
        {
            base.FillValueConverters(registry);

            registry.AddOrOverwrite("NullableBooleanToVisibility", new NullableBooleanToVisibilityConverter());
            registry.AddOrOverwrite("BooleanToVisibility", new BooleanToVisibilityConverter());
            registry.AddOrOverwrite("LogicNot", new LogicNotValueConvert());
            registry.AddOrOverwrite("DateTimeString", new DateTimeStringValueConvert());
        }


        protected override void InitializeIoC()
        {
            base.InitializeIoC();

            Mvx.RegisterSingleton<ICryptography>(new AndroidCryptography());
        }
    }
}

MvxViewModel

在Mvvm框架中,ViewModel起到后台数据与表现层之间桥梁的作用。ViewModel主要实现对后台业务的调用以及客户端业务逻辑, View层通过对ViewModel对象的绑定实现数据的呈现。

MvxViewModel主要方法:

image

InitFromBundle、ReloadFromBundle、SaveStateToBundle三个方法主要实现了实例支行时状态的保存及加载。

InitFromBundle:实例初始化时,如何从内存初始化当前实例的数据。

ReloadFromBundle:实例被激活时,如何从缓存重新加载数据。

SaveStateToBundle:实例被切换到后台时,如何将当前状态保存到缓存。

其基类的主要方法,实现了ViewModel之间导航的方法。

image

Close:关闭指定的ViewModel,一般是关闭当前ViewModel,Close(this)

ShowViewModel:显示指定的ViewModel。MvvmCross会根据指定的ViewModel查找关联的View,并显示相应的View。

Mvx

Mvx是一个静态类,在MvvmCross框架是一个很重要的对象。实现了Ioc、异常工厂、调试信息工厂等。

需要说明的是这里实现的Ioc是一个简化版本的Ioc,不支持泛型、不支持多对象导出,当有多个对象符合条件时,只会导出符合条件的第一个对象。

注册对象时使用RegisterSingleton,当获取对象时使用CanResolve和Resolve方法实现对象的导出。

image

小结

本小节对MvvmCross中常用的对象做了简单的说明。如有未尽之处或错误,请指教。

下次我们讲一下MvvmCross的数据绑定。

mywx

原文地址:https://www.cnblogs.com/phoenixdong/p/6446042.html