欢迎大家加入以下开源社区

Xamarin-Cn:https://github.com/Xamarin-Cn

Mvvmcross-Cn:https://github.com/Mvvmcross-Cn 

(另外微信订阅号 Xamarin 所有者@善友兄也给予了运营权限,后面将开始陆续运营起来,给大家推送相关的文章)

简介

相信做了开发有一定经验的人都知道IOC的存在,而Xamarin.Android中还没有IOC的存在。特别是在Xamarin.Android下,如果仅仅只是显示简单的数据,就需要通过很多的FindViewById来查找组件,并且还要负责呈现,今天我们将通过学习MVVMCross组件来简化这些操作,达到PCL部分的最大化,下面我们以一个官方的DEMO来学习。

题外话:

由于公司的发展需要,需要招聘Xamarin方面的人才,如果你对Xamarin感兴趣的可以直接联系楼主,现在我们要召集8个人进行这方面的培训,所以只要有C#基础,并且有很强的兴趣都可以来。并且在产品完成后我们将会把开发的经验都撰写成博客发表,造福整个Xamarin(Q+976691141)。 

PCL部分

基础准备

首先我们需要新建一个名为“TipCalc.Core”的“类库(可移植)”的项目,并且我们需要按照下图选择对应的平台:

如果你的平台没有红色框住的部分也没有问题的,因为当前主流的PCL的方案是Profile259,如果你要查看你新建的类库是不是259可以查看项目的csproj文件,就是{项目名}.csproj,用记事本打开,然后定位到这个位置就可以看到了:

警告:

如果上面的PCL部分你按照我的选择之后,确定按钮是禁用的,就需要跟着下面的教程来解决这个问题,首先我们需要打开下面这个文件夹:

C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETPortable\v4.5\Profile\Profile78\SupportedFrameworks

将该文件夹中的以下文件复制:

如果不存在“Xamarin.iOS.Unified.xml”也没有关系,之后我们打开下面这个文件夹:

C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETPortable\v4.5\Profile\Profile259\SupportedFrameworks

将上面的文件复制到其中,然后重启VS就可以解决问题了。

项目搭建

删除Class1.cs文件

我们并不需要使用该文件

安装MvvmCross

我们打开“程序包管理器控制台”输入以下指令后回车:

Install-Package MvvmCross.HotTuna.MvvmCrossLibraries

添加Tip Calculation 服务

创建一个名为“Services”的文件夹,并在该文件夹中新建一个名为“ICalculation”的接口,具体的内容代码如下所示:

 namespace TipCalc.Core.Services
{
public interface ICalculation
{
double TipAmount(double subTotal, int generosity);
}
}

并在该文件夹中新建一个Calculation类实现上面的接口,具体代码如下:

 namespace TipCalc.Core.Services
{
public class Calculation : ICalculation
{
public double TipAmount(double subTotal, int generosity)
{
return subTotal * ((double)generosity)/100.0;
}
}
}

以上部分在实际项目中我们可以认为是应用服务层。

添加视图模型

视图模型将会连接最终的界面与上面的服务层,而为了达到这些效果,我们的视图模型必须继承自MvxViewModel。下面我们先新建一个ViewModels文件夹并新建一个TipViewModel类,具体的代码如下所示:

 namespace TipCalc.Core.ViewModels
{
public class TipViewModel : MvxViewModel
{
private readonly ICalculation _calculation;
public TipViewModel(ICalculation calculation)
{
_calculation = calculation;
} public override void Start()
{
_subTotal = ;
_generosity = ;
Recalcuate();
base.Start();
} private double _subTotal; public double SubTotal
{
get { return _subTotal; }
set { _subTotal = value; RaisePropertyChanged(() => SubTotal); Recalcuate(); }
} private int _generosity; public int Generosity
{
get { return _generosity; }
set { _generosity = value; RaisePropertyChanged(() => Generosity); Recalcuate(); }
} private double _tip; public double Tip
{
get { return _tip; }
set { _tip = value; RaisePropertyChanged(() => Tip);}
} private void Recalcuate()
{
Tip = _calculation.TipAmount(SubTotal, Generosity);
}
}
}

通过上面的代码我们可以看到,视图模型的构造函数要求传入一个实现了ICalculation接口的参数,而这个过程将会有IOC帮我们完成。剩下的我们可以看到我们重写了Start方法用来给视图模型中的值赋初始值,并且在每个值改变的同时还调用了Recalcuate方法来重新计算。

OK,完成这些之后,我们还需要一个启动项对依赖注入进行配置,并且指定初始显示的视图模型,我们直接在项目根目录下新建一个App类,并且该类需要继承自MvxApplication类,并在构造函数中写入以下代码:

 namespace TipCalc.Core
{
public class App : MvxApplication
{
public App()
{
Mvx.RegisterType<ICalculation,Calculation>();
Mvx.RegisterSingleton<IMvxAppStart>(new MvxAppStart<TipViewModel>());
}
}
}

其中我们可以看到我们通过Mvx.RegisterType对IOC进行了配置,这样IOC才能够知道在需要ICalculation接口的时候实例化哪个类,而下一行的代码则是指定初始的视图模型,也就是首页,完成上面这些配置后我们的PCL部分完成了,可以通用于Android和IOS。

 

Android UI呈现

首先我们创建一个“Blank App(Android)”项目,项目名为“TipCalc.UI.Droid”。并将项目默认生成的MainActivity.cs文件和Resources/Layout文件夹下的Main.axml删除并添加TipCalc.Core.csproj引用。

安装MvvmCross

跟PCL部分一样,我们还需要安装对应的类库:

Install-Package MvvmCross.HotTuna.MvvmCrossLibraries

添加MvvmCross Android绑定资源

该部分是为了我们能够在界面中使用bind属性,所以我们需要在Resources/Values文件夹下新建一个xml资源,名字可以为“MvxBind”,对应的内容如下:

 <?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="MvxBinding">
<attr name="MvxBind" format="string"/>
<attr name="MvxLang" format="string"/>
</declare-styleable>
<declare-styleable name="MvxListView">
<attr name="MvxItemTemplate" format="string"/>
<attr name="MvxDropDownItemTemplate" format="string"/>
</declare-styleable>
<item type="id" name="MvxBindingTagUnique"/>
<declare-styleable name="MvxImageView">
<attr name="MvxSource" format="string"/>
</declare-styleable>
</resources>

添加启动类

虽然PCL中有启动项了,但是我们需要在特定中进行注册,所以我们还需要新建一个Setup类,并且该类的主要内容如下:

 namespace TipCalc.UI.Droid
{
public class Setup : MvxAndroidSetup
{
public Setup(Context applicationContext)
: base(applicationContext)
{
} protected override IMvxApplication CreateApp()
{
return new App();
}
}
}

主要作用就是将App实例化并返回,以便在特定平台中进行初始化。

添加视图

我们需要在Resources/Layout文件夹下新建一个视图名为View_Tip.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/TipCalc.UI.Droid"
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:text="SubTotal" />
<EditText
android:layout_width="fill_parent"
android:layout_height="wrap_content"
local:MvxBind="Text SubTotal" />
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Generosity" />
<SeekBar
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:max="40"
local:MvxBind="Progress Generosity" />
<View
android:layout_width="fill_parent"
android:layout_height="1dp"
android:background="#ffff00" />
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Tip to leave" />
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
local:MvxBind="Text Tip" />
</LinearLayout>

通过其中的内容我们可以看到,其中多了一个MvxBind属性,通过这个属性我们可以直接将控件的属性直接与ViewModel中对应的属性直接关联起来,这样我们可以省去与控件交互的部分,但是我们还是需要Activity来将界面与我们的ViewModel进行关联。

添加视图类

我们直接新建一个名为TipCalcView的活动,然后将其继承的类改成MvxActivity,具体的代码如下:

 namespace TipCalc.UI.Droid.Views
{
[Activity(Label = "Tip", MainLauncher = true)]
public class TipView : MvxActivity
{
public new TipViewModel ViewModel
{
get { return (TipViewModel) base.ViewModel; }
set { base.ViewModel = value; }
} protected override void OnViewModelSet()
{
base.OnViewModelSet();
SetContentView(Resource.Layout.View_Tip);
}
}
}

完成这些之后,直接运行,我们可以看到调整进度条的同时,Tip to leave的值会跟着动,完全是实时的。

当然原生的方式与MvvmCross的方式是可以直接并存的。

Xamarin.Android之MvvmCross的更多相关文章

  1. Xamarin. Android实现下拉刷新功能

    PS:发现文章被其他网站或者博客抓取后发表为原创了,给图片加了个水印 下拉刷新功能在安卓和iOS中非常常见,一般实现这样的功能都是直接使用第三方的库,网上能找到很多这样的开源库.然而在Xamarin. ...

  2. Xamarin.Android和UWP之MVVM的简单使用(二)

    0x01 前言 前面一篇,Xamarin.Android和UWP之MVVM的简单使用(一),主要讲了MvvmLight的简单使用 这篇主要讲讲MvvmCross的简单使用,例子的话,还是和上篇的一样. ...

  3. Xamarin.Android和UWP之MVVM的简单使用(一)

    0x01 前言 就目前而言,MVVM可以说是挺流行的,无论是web端还是移动端,web端的主要代表angularjs,avalonjs等, 移动端(xamarin,uwp)的代表应该是mvvmligh ...

  4. Xamarin.Android中使用ResideMenu实现侧滑菜单

    上次使用Xamarin.Android实现了一个比较常用的功能PullToRefresh,详情见:Xamarin. Android实现下拉刷新功能 这次将实现另外一个手机App中比较常用的功能:侧滑菜 ...

  5. XAMARIN.ANDROID SIGNALR 实时消息接收发送示例

    SignalR 是一个开发实时 Web 应用的 .NET 类库,使用 SignalR 可以很容易的构建基于 ASP.NET 的实时 Web 应用.SignalR 支持多种服务器和客户端,可以 Host ...

  6. XAMARIN ANDROID 二维码扫描示例

    现在二维码的应用越来越普及,二维码扫描也成为手机应用程序的必备功能了.本文将基于 Xamarin.Android 平台使用 ZXing.Net.Mobile  做一个简单的 Android 条码扫描示 ...

  7. 我正在使用Xamarin的跨平台框架—Xamarin.Android回忆录

    一.缘起 在自己给别家公司做兼职外包的时候,已经明确知道外包的活不是那么好干的,一般在经历了初期热血澎湃的激情后,逐渐冷淡,愤怒,再冷淡,再愤怒…,听上去好像高潮迭起,但令人尴尬的是,这高潮迭起我们都 ...

  8. APP并非一个人在战斗,还有API—Xamarin.Android回忆录

    前言 一般来说,一个客户端APP并非独立存在的,很多时候需要与服务器交互.大体可分为两方面的数据,常规字符串数据和文件数据,因为这两种数据很可能传输方式不一样,比如字符串之类的数据,使用HTTP协议, ...

  9. Xamarin.Android通知详解

    一.发送通知的机制 在日常的app应用中经常需要使用通知,因为服务.广播后台活动如果有事件需要通知用户,则需要通过通知栏显示,而在Xamarin.Android下的通知需要获取Notification ...

随机推荐

  1. 修改了chrome的官方的有道词典插件,添加了生词本的功能

    项目地址+导入教程 https://github.com/cclient/chrome-extensions-youdaowithwordnode

  2. [Note] changing building platform from vs 2013 to vs community 2015

    The error turned out as "undefined linkage"(The same as you haven't use some function that ...

  3. WinForm开发之取送货管理1

    一.取送货管理项目需求 该系统的业务背景如下:客户是一个针织半成品生产加工作坊,有很多生产加工人员从客户工厂那里取走半成品,加工成成品后送回来.客户根据加工每种半成品的加工单价和完成数量,付费用给生产 ...

  4. springMVC 相对于 Structs 的优势

    智者说,没有经过自己的思考和估量,就不能接受别人的东西.资料只能是一个参考,至于是否正确,还得自己去分辨 SpringMVC相对于Structs的几个优势: 1.springMVC安全性更高,stru ...

  5. 【java】:通用小知识

    1.将String字符串放在最前面 为了防止偶发性的NullPointerException 异常,我们通常将String放置在equals()函数的左边来实现字符串比较,如下代码: // Bad i ...

  6. J2EE中EL表达式

    EL全名为Expression Language. EL语法很简单,主要的语法结构是${sessionScope.user.sex}所有EL都是以${为起始.以}为结尾的. 上述EL范例的意思是:从S ...

  7. 实验 2 用C语言编写简单程序

    #include<stdio.h> int main() { int x,y; printf("enter x:"); scanf("%d",&am ...

  8. tomcat详情

    [转载]http://grass51.blog.51cto.com/4356355/1123400

  9. Bootstrap自带的一些预定义的按钮颜色

    浅蓝色 btn-info 被用在那些用户可能会采取的操作上. 红色btn-danger被用来提醒用户该操作具有“破坏性”,例如删除一张猫的图片.

  10. iOS进阶_动画的多种实现方式

    一.UIView动画 //UIView动画有开始beginAnimation,有结束commitAnimation    //第一步:开始UIView动画    [UIView beginAnimat ...