关于Xamarin、Qml、数据绑定、MVC、MVVM 相关的散讲
- 关于Xamarin、Qml、数据绑定、MVC、MVVM 相关的散讲
- SURFSKY 2017.02
- 最近又在学习Xamarin了?为什么是“又”?有几个利好消息,让我重新拾起它:
- ()微软去年收购了Xamarin,而且免费。原先的费用会吓死人,而且按人头+平台来收费。
- ()Xamarin.Forms 的出现,UI层也可以复用了,不像原先只能逻辑层代码复用。
- ()IDE增强:
- Xamarin Forms Previewer,可以直接预览 XAML 的外观。
- XAML 智能感应的增强,现在编写XAML舒服多了。原先编写XAML可不是件轻松的事情,所以之前的教材全部都是用C#写的UI,这很不利于视图和逻辑的分离。
- Visual Studio for mac 发布,可替代原先的 Xamarin Studio for mac。毕竟,在mac下编写ios/Android app无论性能还是便利性都要比在windows上好得多。
- 不愧是宇宙最强IDE开发商,一接手Xamarin,编辑器就增强了:)
- ()真正的一个语言可以编写跨平台移动app,包括后台、ios、android、windows uwp 等
- 数据接口和后台:用 asp.net 写即可
- 移动客户端API:Xamarin 已用C#封装好,如果需要平台专用功能,直接调用即可。
- 这很利于节省成本、积累技术、简化员工招招聘和培训。
- ()性能
- 对于ios平台,xamarin是将c#编译成原生的代码。android是嵌入了.NET运行时。
- 实测试了下,ios下没有任何问题,3秒左右进入主界面,进去后性能就和原生的没有区别了
- android的启动略慢,估计要5秒,进去后性能没有问题。
- 加个欢迎屏可以稍微减缓客户等待的焦虑感。
- 当然还有缺陷和期望
- 缺陷
- Xamarin.Forms 的控件是转化为各平台原生控件的,也就是说,这些控件在各平台上外观都有区别!
- IED
- 复杂的 XAML previewer展示不出来。
- 无法拖拽控件快速设计页面。
- VS MAC 有时候屏幕刷新不过来,一片白。
- 经常出现“不是在活动配置中生成的项目”,无法加载项目。
- 启动速度还是慢了点,位于可容忍的边缘。
- 没有官方的、统一的移动平台功能 API 库。
- 类似PhoneGap那样的,访问摄像头、传感器等API,一套代码各平台通用。
- 现有的这些功能API是分散在各平台自己的库里的,学习一个统一库与学习多平台类库,工作量当然不一样。
- 早些年有Xamarin.Mobile项目,但与Xamarin.Forms不兼容已经废弃了。
- 现在这些功能API插件处于散乱琐碎状态,要自己一个个去Xamarin Compoents/GitHub上找。
- 期望
- 不知什么时候可以直接拖拽 Xamarin Forms 控件,一个平台也行啊。
- 加快 Xamarin Form Android app 启动速度。
- 需要一套外观一致的 Xamarin Forms UI 库,但短期内不会有,要我们直接写了(*)
- 官方推出统一的跨平台移动功能 API 库:Xamarin.Forms.Mobile(*)
- 备注
- 当然 Visual Studio for mac 还是预览版本,等正式版估计BUG会少一些。
- (*)打算启动这两个项目,欢迎有共同志向的同学参与。
- 相比较 Qt
- 性能还是Qt占优的,毕竟底层是C++写的。但Xamarin的性能也在可容忍范围内,主要是启动时间稍慢了点。
- APP 大小。
- 都在20M以上,
- Qt
- V-Play apps 基于Qt的游戏引擎 52.4M
- 新发布的 Qt .8据说可以裁剪库的大小,将APP压缩到4、5M内
- Xamarin 我也搞不清楚了。
- Xuni Explorer 只有 5.6 M
- Evlove 有46.1M
- 随便编译个debug版本的,估计有60多M,release的还没试验
- 虽然说理论上 Qml 可以摆平一切界面问题,但我们不可避免的要涉及到各平台的插件,那么你真正需要学习的语言有:
- QML :
- Javascript :
- C++ : Qt类库
- Object-C :
- Android :
- ps.真希望Qml能发展成独立的开发语言(参照 swift)
- 强类型
- 可编译
- 简化创建组件语法,直接用new MyItem(),而不是复杂的Qt.CreateComponent.....
- 摒弃js、v4引擎,提供工具将js迁移为标准Qml
- 独立发展 Qml 类库
- 更便利的方式访问c++类库,类似swift那样,只需Import即可使用
- 绑定的前世今生
- 若要监控一个对象的若干属性变化情况,传统写法是为每个要监控的属性加上一个值变更事件,然后让调用者添加这个事件
- public event Event FirstNameChanged;
- public string FirstName {get; set;}
- sample.FirstNameChanged += (o, value)=>txtbox.Text = value;
- 这样很可能要写很多的属性变更事件,而且不能自动给订购者赋值
- 什么是绑定?它事实上做了两件事
- ()监听对象指定属性,若变化,则通知给订购者
- ()给订购者赋值
- 微软给出的官方方案是
- ()绑定系统维护了一个表格(在绑定表达式中指定),字段大致包括:
- object SourceObject : 监听对象
- string SourcePropertyName : 监听对象的属性名称
- object TargetObject : 订购者
- string ValuePath : 赋值路径
- ()让数据实现INotifyPropertyChanged接口
- public event PropertyChangedEventHandler PropertyChanged;
- 若监听对象的属性有变动,则触发这个事件,通知绑定系统
- 这个事件的参数中包含了监听对象和变更的属性名称(SourceObject + SourcePropertyName)
- ()绑定系统去查表,给订购者进行赋值
- TargetObject = SourceObject.SourcePropertyName.ValuePath
- 属性变更通知
- INotifyPropertyChanged接口(属性变更的时候通知下绑定系统,我的哪个属性变更了,快处理啊)
- class Sample : INotifyPropertyChanged
- {
- // INotifyPropertyChanged 接口成员
- public event PropertyChangedEventHandler PropertyChanged;
- // 属性
- private string firstName;
- public string FirstName
- {
- get { return firstName; }
- set
- {
- firstName = value;
- if (PropertyChanged != null)
- PropertyChanged(this, new PropertyChangedEventArgs("FirstName"));
- }
- }
- }
- // 绑定(textBox.Text <= sourceObject.FirstName)
- Sample sourceObject = new Sample();
- textbox.DataBindings.Add("Text", sourceObject, "FirstName");
- sourceObject.FirstName = "Stack";
- 我们做一下封装,加上值相等判断。
- 定义 ViewModelBase
- using System;
- using System.ComponentModel;
- using System.Runtime.CompilerServices;
- namespace Xamarin.FormsBook.Toolkit
- {
- public class ViewModelBase : INotifyPropertyChanged
- {
- public event PropertyChangedEventHandler PropertyChanged;
- protected bool SetProperty<T>(ref T storage, T value, string propertyName = null)
- {
- if (Object.Equals(storage, value))
- return false;
- storage = value;
- if (PropertyChanged != null)
- PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
- return true;
- }
- }
- }
- 让数据模型类继承自ViewModelBase
- public class InformationViewModel : ViewModelBase
- {
- string name;
- public string Name
- {
- get { return name; }
- set
- {
- if (SetProperty(ref name, value, "Name"))
- {
- ...属性已经更新,该干点啥
- };
- }
- }
- }
- Xamarin 的方案(使用 BindableObject)
- 代码
- public RadioButtonGroup : BindableObject
- {
- public static readonly BindableProperty TextProperty = BindableProperty.Create("Text", typeof(string), typeof(Radio), "", propertyChanged: TextChanged);
- private static void TextChanged(BindableObject bindable, object oldValue, object newValue)
- {
- var radio = (Radio)bindable;
- radio.Lbl.Text = (string)newValue;
- }
- public string Text
- {
- get {return (string)this.GetValue(TextProperty);}
- set {this.SetValue(TextProperty, value);}
- }
- }
- this.Icon.SetBinding(Image.IsVisibleProperty, new Binding("ShowRadio", source: this));
- 说明
- 这里的BindableProperty是用于描述这个属性的元信息,如名称、类型、默认值、绑定方向、属性值变更事件
- BindableObject 是 INotifyPropertyChanged 的封装,增加了绑定上下文、属性变更中、属性变更完毕事件等逻辑
- public abstract class BindableObject : INotifyPropertyChanged, IDynamicResourceHandler
- {
- public static readonly BindableProperty BindingContextProperty;
- public object BindingContext { get; set; }
- protected BindableObject ();
- // Methods
- protected void ApplyBindings (object oldContext = null);
- public void ClearValue (BindableProperty property);
- public void ClearValue (BindablePropertyKey propertyKey);
- public object GetValue (BindableProperty property);
- protected virtual void OnBindingContextChanged ();
- protected virtual void OnPropertyChanged ([CallerMemberName] string propertyName = null);
- protected virtual void OnPropertyChanging ([CallerMemberName] string propertyName = null);
- public void RemoveBinding (BindableProperty property);
- public void SetBinding (BindableProperty targetProperty, BindingBase binding);
- public void SetValue (BindablePropertyKey propertyKey, object value);
- public void SetValue (BindableProperty property, object value);
- protected void UnapplyBindings ();
- // Events
- public event EventHandler BindingContextChanged { add; remove;}
- public event PropertyChangedEventHandler PropertyChanged {add; remove;}
- public event PropertyChangingEventHandler PropertyChanging {add; remove;}
- }
- 单向数据绑定和双向数据绑定
- 单向:model的变更会刷新view,view上做任何操作都不影响model
- 双向:model的变更会刷新view,view的变更会刷新model
- 个人只喜欢用单向的,理由呢:
- 喜欢实打实的代码来控制数据刷新,双向的数据绑定总觉得不放心
- view的交互,常常带了逻辑控制,不仅仅是给model赋值,这不是双向数据绑定能解决的。
- 其它
- Qt QML的属性、绑定、属性变更事件实现起来非常优美和简单
- A
- {
- property int Property1;
- // 编译器会自动生成类似以下方法
- // bool onProperty1Changing(o, oldValue, newValue){...}
- // void onProperty1Changed(o, oldValue, newValue) {....}
- }
- b.Property2 = a.Property1; // 绑定这两个对象的属性(单向绑定)
- 建议 C# 优化编译器,或者提供语法糖之类的东西(如propety关键字)
- public readonly property string Name;
- 编译器自动实现:
- getter、setter
- INotifyPropertyChanged 接口
- PropertyChangingEvent
- PropertyChangedEvent
- 绑定逻辑
- 事实上,这个功能10来年前的 Delphi 就实现了
- 什么是 MVC
- 这是将界面、逻辑、数据隔离的一种方案,这其实也是绑定的一种实现,不过是页面级别的。
- Model : 数据
- View : 视图
- Controller : 控制器
- 视图的呈现由控制器控制,视图的数据(模型)也由控制器提供
- TODO: 补一个简单的示例
- ASP.NET MVC
- 是一个controller对应多个view
- 它的controller主要就是个跳转器,根据客户端请求,组装数据并提供给某个视图,渲染到客户端
- 疑问:
- 大的页面用controller跳转好理解
- 但小的交互,如按钮点击页面上的某个label变个文字,这个也交给controll是不是太琐碎了?
- 这个还是交给页面客户端自己处理会更合适,但这要写js了
- 其实传统的 Windows Form 也可以看为一种MVC
- View部分可由设计器创建
- View的数据展示、交互(如点击事件)在后台代码中,这个可以看成Controller
- 不过这种方式是一个view对应一个controller,这个controller是这个view专用的
- ios-objectc 的MVC
- 这货和 Windows Form 差不多,也是一个视图对应一个专用的控制器
- 挂MVC的头衔,行Windows Form的行当。
- 什么是 MVVM
- 这是将界面和数据完全隔离的一种方案
- Model : 模型
- View : 视图
- ViewModel : 视图模型
- 传统的页面数据展示,可以是混杂的,既有数据绑定,也可以掺杂代码指定。如:
- TODO:来段 MVVM 的示例代码
- 可以看出,MVVM是一种更极端的、界面和数据完全隔离的方案:
- 它定义了一个叫 ViewModel 的东西,这个也是一种Model,但专用于视图
- 视图的赋值只能用 ViewModel,不能用其它方式
- 我们必须为每个 View 定制一个 ViewModel。
- 评价
- 好处:完全隔离视图和数据、只要约定好数据接口(ViewModel)就行
- 坏处:必须为每个视图都定制 ViewModel,这会增加代码量
- ps
- - 出了个 Xamarin Live Player 的东东,可以在手机上展示程序运行效果
- android版本的可以直接下载,ios版本的还在testflight中
- https://docs.microsoft.com/zh-cn/xamarin/tools/live-player/
关于Xamarin、Qml、数据绑定、MVC、MVVM 相关的散讲的更多相关文章
- MVP MVC MVVM 傻傻分不清
最近MVC (Model-View-Controller) 和MVVM (Model-View-ViewModel) 在微软圈成为显学,ASP.NET MVC 和WPF 的Prism (MVVM Fr ...
- MVC & MVVM
什么是MVC,什么是MVVM? 面向过程 --> 面向对象 --> MVC --> MV* 面向过程: 开发人员按照需求逻辑顺序开发代码逻辑,主要思维模式在于如何实现.先细节,后整体 ...
- mvc/mvvm小小的总结
mvc/mvvm 阮大神博客 mvc 分为三层,其实M层是数据模型层,它是真正的后端数据在前端js中的一个映射模型,他们的关系是:数据模型层和视图层有映射关系,model改变,view展示也会更改,当 ...
- 【extjs6学习笔记】1.2 初始:MVC MVVM
模型 这表示数据层.该模型可以包含数据验证和逻辑来保持数据.在 ext js 中, 大多数模型都与一个数据存储一起使用. 视图 这表示用户界面. 是用户在屏幕上看到的组件. 在每次互动的用户与应用程序 ...
- 前后端分层架构MVC&MVVM
早期 特点 页面由 JSP.PHP 等工程师在服务端生成 JSP 里揉杂大量业务代码 浏览器负责展现,服务端给什么就展现什么,展现的控制在 Web Server 层 优点 简单明快,本地起一个 Tom ...
- JavaScript富应用MVC MVVM框架
对框架的挑选 Ember.js.Backbone.js.Knockout.js.Spine.js.Batman.js , Angular.js 1. 轻量级的应用选择哪一个会比较好?2. 那一个比较简 ...
- 通俗理解 MVC , MVVM
MVC 也就是Model-View-Controller 的缩写,就是 模型-视图-控制器 : Model :管理数据 View :视图展示 Controller :响应用户操作,并将 Model 更 ...
- MVC,MVVM模式的理解
基本上,我们的产品就是通过接口从数据库中读取数据,然后将数据经过处理展示到用户看到的视图上.当然我们还可以从视图上读取用户的输入,然后通过接口写入到数据库.但是,如何将数据展示到视图上,又如何将用户的 ...
- 我的架构设计~用层关系图说说mvc,mvvm,soa,ddd
下面是按着我所接触的架构模式,开始一个一个的说一下 第一 标准架构 三层结构
随机推荐
- Class.forName()+Class.forName().newlnstance()和new语句和初始化块+static初始化块+构造方法之间的关系
先上代码 class A{ int a; static {System.out.println("载入类时执行");} public A() { ...
- JS编码方式
1. escape(): 采用unicode字符集对指定的字符串除0-255以外进行编码.所有的空格符.标点符号.特殊字符以及更多有联系非ASCII字符都将被转化成%xx格式的字符编码(xx等于该字符 ...
- 201771010126.王燕《面向对象程序设计(Java)》第六周学习总结
实验六 继承定义与使用 实验时间 2018-9-28 1.实验目的与要求 (1) 理解继承的定义: 继承就是用已有类来构建新类的一种机制,当你继承了一个类时,就继承了这个类的方法和字段,同时你也可以在 ...
- Elastic 之倒排索引(二)
常规索引建立: 文档-->关键词的映射过程(正向索引) 缺点:费时 便利全部文档 倒排反向建立索引: 关键词-->文档的映射 反向到倒排索引:将索引的关键词出现的文档的位置和出现频率通过文 ...
- Linux下提权常用小命令
有些新手朋友在拿到一个webshell后如果看到服务器是Linux或Unix操作系统的就直接放弃提权,认为Linux或Unix下的提权很难,不是大家能做的,其实Linux下的提权并没有很多人想象的那么 ...
- 记一次FileZillaServer提权
前段时间检测一个企业网站,在检测该企业的一个下属公司的网站时通过用户名admin和密码123456进入了后台,后台目录就是公司汉语拼音+admin,诸如xxxadmin这种形式的.在后台通过“产品图片 ...
- C博客作业01--分支,顺序结构
本章学习总结(2分) 1.1思维导图 1.2本章学习体会及代码量学习体会 1.2.1学习体会 本周初次接触C语言,一开始难度较大,很多代码都看不懂,书里面的章节要看很多遍.开始编写代码时也遇到很多困难 ...
- 安装Office2010出现MSXML版本6.10.1129.0错误
在键盘上按“win+R”组合键出现图图示界面后,输入“regsvr32 /u msxml6.dll”,点击“确定”. 出现图示显示后,点击“确定”,并同时去试试office是否能够安装了. 如果上 ...
- c++第三次实验
第一题: 先把代码贴上来 main.cpp #include <iostream> #include <cstdlib> #include<conio.h> #in ...
- 2018-2019-2 20165225《网络对抗技术》Exp1 缓冲区溢出实验
2018-2019-2 20165225<网络对抗技术>Exp1 缓冲区溢出实验 声明 虽然老师在邮箱中要求要把虚拟机名改为个人名字缩写,但是我的kali好像不是很听话...重启数次也没用 ...