陈仁松-跨端解决方案MAUI介绍

今天和大家的分享主题是:微软跨端解决方案 MAUI 的介绍。分为以下几个小部分:

  1. MAUI 介绍
  2. 布局
  3. 字体
  4. 原生控件
  5. MAUI控件
  6. 另类玩法

MAUI 介绍

MAUI 的英文名称是 .NET Multi-platform App UI, 它的前身其实是 Xamarin.Forms 的框架演变过来的,然后做了很多改进。MAUI 其实就是两套的 UI 方案。第一套是以 XAML 为基础的,另外一套是以 Web 为基础的。以 Web 为基础的那套其实是以 Blazor 作为一个载体,它基本上是跟原来的 WPF 以及 UWP 的开发是类似的。

然后我们可以看一看它现在支持的平台,官方支持应该是有五个,不算 Linux。Linux 是社区支持了,现在没有合并进来。MAUI 应该在五月底微软就已经正式发布了。 我们可以看到像 Blazor MAUI  的所有的版本支持,就是不同平台的版本,其实都是比较的低的,因为 Blazor 需要 web key 的一个内核。所以这个在低版本上支持并不好,在 WIN10 的版本上,基本上已经两个是一样的。因为 MAUI 的底层它是支持 Win UI 的,所以 WIN10 的版本要支持 1809,以及以上的 WIN11。

我们本次分享的主要目标是希望大家能够学完之后,了解 MAUI 的一些基础知识,以及后续能够自主的开发。

接下来我们介绍的主要也是以 JAVA 为基础的,因为 Blazor 为基础基本上就跟 web 相关了, 大家如果会前端的一些知识,基本上也可以完成。然后这里面以 JAVA 为基础来介绍一下它和之前的一个 JAVA 的开发有什么不同。

 我们来看一看 MAUI 的一个项目结构,可以看到它的一个项目结构是一个单项目的,跟原来的一个,就是大家知道,如果你要开发像 UWP,像 WPM,要创建不同的工程, 比如说安卓开发创建一个安卓的工程,IOS 创建 iOS 工程。但是在 MAUI 里面,这已经合并了,同时它们也共享资源,然后可以通过按需来访问指定的一个   API。

下面的讲解中使用到的文件,大家可以通过链接 https://www.51aspx.com/code/MAUIDemoCRS 进行下载。在该项目中有多个 Demo,我们依次来介绍一下:

  1. StackLayout:类似 StackPanel ,都是用 Orientation 这个属性来指定元素的方向,默认都是Vertical,在MAUI上有两个特别的StackLayout,HorizontalStackLayout 和 VerticalStackLayout,这两个微软官方文档介绍为更高性能的StackLayout,建议大家使用
  2. AbsoluteLayout:是绝对定位的容器,从左上角开始,实现了按比例定位和调整大小的功能
  3. Grid:基本和UWP的Grid一致,这里不做过多的介绍
  4. FlexLayout:非常常用强大的布局,基于w3c标准的css flex box样式
  5. HslColor:HSL字体的标记扩展
  6. LightColor:实现一种已知颜色的浅色的标记扩展
  7. FontAwesomeMAUI:FontAwesomeUWP迁移至MAUI
  8. CustomButton:创建Handler实现原生控件
  9. EffectButton:创建Effect实现原生控件效果
  10. ImageButton:封装实现MAUI控件
  11. HttpServer:嵌入Kestrel实现Http Server

然后我们来看看它是怎么做的,其实它本质上也是比较简单的 。就是用微软的一个宏定义,我们来看看,把这个代码生成一遍。我们来看一看它是怎么来实现这个东西。来编译,看一下它编译的产物是什么?

这是 Windows 下编译的一个产物。那我们再看一看安卓下的一编译产物。这两个类,大家可以看到,其实是不一样的,像 Windows 上它是有个 WinUI 的入口,它通过这个文件来启动 APP 的。

在安卓上其实不是的,安卓上是在这里。它每个入口文件是不一样的。其实本质上是因为它通过了宏定义来实现不同平台编译不同平台的代码。比如说在 Platforms,如果你编译的是Android代码,它只会编译这下面目录下面的代码,如果是Windows,那它只会编译Windows目录下面的代码。

当然如果你在别的地方写的话,你可以这么写,就是用宏定义。If Windows,那这样写的代码就是只编译 Windows 代码,所以它本质上是用宏定义来把整个项目变成单一的一个项目的。

然后我们来看看 MAUI 的另外一个特性,就是热重载,这个大家应该比较熟悉,因为你用 donate6.0,基本上都应该会知道有热重载这个功能,它可以支持 .net 代码的重载。
 

我们可以编译一个示例看一下,这是 Windows的一个启动项目。默认为 Hello World!然后我们改成 Hello Simon。可以看到这个直接就更新了,不用再编译代码。

之前提到过 .net 的代码也可以。你看到这里,点击每个 Clicked。这个点击的时候,它每次都会增加一次。

我们在这里加一个代码写。count = 1000 试一下。再点一下可以看到就直接生效。这个非常方便我们来开发调试,这两个是 MAUI 里面非常方便的一个开发特性。

布局

接下来我要跟大家讲的是怎么从一个基础的知识来学习一个 MAUI,那我们就来看一看整个 MAUI 在布局上怎么做的。

布局上呢,官方上有五个大的 Layout 来支持:

1.StackLayout:如果你开发过 uwp、wpf。你就应该知道它那四项 StackPanel, 都是用 Orientation 这个属性来确定元素的方向,默认都是 Vertical。然后 MAUI 其实有两个非常特别的 StackLayout,一个是 HorizontalStackLayout,另一个是 VerticalStackLayout。这两个呢,官方文档介绍是更高性能的。所以大家如果已经明确了方向,比如说如果你知道垂直还是水平的  ,那我建议直接用 HorizontalStackLayout 或者 VerticalStackLayout。

2.Grid:基本上就是跟 UWP 一致,这里不做太多的介绍。

3.FlexLayout:是非常强大的一个布局,基本上是基于W3C标准的 css flex box的样式。

4.AbsoluteLayout:是一个绝对定位的容器,如果你开发这个响应式布局的,应该用的会比较少,因为它的整个布局是相对比较不好调的。如果你特别厉害的话,可以尝试使用,这个布局是从左上角开始,然后是可以实现等比例的定位和调试,它有四个参数 x、y、width 和 height。

5.BindableLayout:其实它跟上面四个有很大的一个区别,它其实是像 ListView 里面的 itemSource。基本上就是一个空间集合,但不适合特别长、特别多的数据展示,为什么呢?因为如果你在用 ListView 它是用虚拟化的。也就是说如果你的数据有几千条,界面上展示出来的 ListView,它只是你看到那部分它才会加载,没有看到的那部分它是加载不到界面上。所以它不能用特别多的集合的元素。

那我们用 Demo 来简单看一看 StackLayout 的一个情况,我们先做一个纵向的布局、垂直的布局,然后这样的话,它的垂直方向的话,它其实是无限延展,所以它填不满,你如果是要做一个响应式布局的话,他是没办法填满。然后如果下面放了一个水平的布置,它的横向的也是没有办法填满的。而这个布局是非常常用的,但它不适合做这种全局的一个布局。

Grid 它就比较适合。如果你想做一个全局的一个响应式的话,可以用 Grid。基本上刚才说的那个布局,我们是把它切成三行三列,然后在首行跨三行。

然后我们再看一看,像刚才的 FlexLayout 和 AbsoluteLayout 这两个,要不就后面大家自己看一下DEMO,因为这两个呢,其实相对来说,用的比较少。FlexLayout  会用的比较多,但 AbsoluteLayout 用的比较少,而且比较复杂,大家可以看一下DEMO。

然后这里插一下介绍一下 BindableLayout,他可以定义一个空的 View,然后我们可以设置 StackLayout 的一个属性,我们来编译一下。如果你用了热重载的话,有的时候他是不能生效的,比如说你这个页面已经渲染过了,如果你再改构造函数的话,它并不会生效,所以我这里要重新编译一下,大家知道一下这个情况。

我们可以看一看 BindableLayout,这是一个比较特殊的,你可以看到我们这里创建了两个list,然后它其实基本上就是 ItemTemplate,就跟 ListView 基本上是一致的,然后 EmptyView,那就是如果数据为空的时候展现什么。就把这个 ItemSource 不要设置。

关于布局呢,大家可以再细细的研究一下,因为或许这个不是说一下子就能学会了,需要去深刻了解。这里面比较常用的就是 StackLayout 以及 Grid,这两个用好,基本上大部分的布局可以,然后再加强,应该可以用 FlexLayout 。

然后讲的布局,我跟大家再介绍一下,更重要的一个就是标记扩展。这个标记扩展其实什么意思呢?就是大家可以看到所有的 XAML 都是有标记的,都是用标签来表示的,但是它的标签很多都是定义好的,那我们想标记扩展,它其实相当于就把原来的 .NET 代码里面的一些能力赋予给 XAML,让 XAML 变得更加强大。

然后大家可以看,这些都是标题扩展,像 StaticResource,DynamicResource,这些都是标记扩展,这里面重点介绍一下三个特殊的标记扩展:

1.OnPlatform:他是来标记就是你是在哪个平台,属于哪个平台的。

2.Onldion:他其实标记的是你在哪种设备上,比如说像手机,比如说像平板,比如说像桌面的电脑。

3.AppThemeBinding:它这个就是主题,也就是说你可以指定就是大家知道一下,安卓,IOS和Windows都有一个暗黑模式和白天的模式。那这两个模式的切换就是这个 AppThemeBinding 来实现。

我们可以看一看怎么来用。看一下这个DEMO基本上也写完了。

我们来看看 OnPlatform 放这个代码的意思是什么呢?这个代码其实写了安卓和iOS,以及说默认的一个yellow。这个告诉你说,如果是iOS它就是红色,如果是安卓就是绿色,如果不是这两个,那就是默认了,就是yellow。有点像那个Switch case before。基本上跟这个句式类似的,在 OnIdiom 这个也是一样的,就是告诉你如果是手机、平板和桌面操作系统,就是什么样的颜色,如果不是它什么。

这个 AppThemeBinding 告诉你,如果你用的是白天的模式的话就是green,如果你用的是暗黑模式的话就是 Red。我们来运行一下。

因为我不是安卓和iOS,所以我是黄色。因为我是桌面操作系统,所以这个是blue,然后我现在用的是白天的一个模式,所以这个字的颜色是green。我们可以看一看,是不是把个性化里面的这个主题颜色改一下就会变了。

把它改成黑色的主题吧。可以看到它这个颜色已经变了,已经帮你来实现了说那个主题的快速切换。这个非常方便,比 UWB 开发还方便很多,因为 UWB 开发可能需要你自己来实现类似的功能。

我们来看一看 OnPlatform 是不是在安卓上能实现特定的效果,我们要切换安卓的话,在这里有个框架,我们把这个切换成 .NET 安卓,好。我们切换完之后呢,我们可以去就是运行一下安卓这个虚拟机,看看整个的一个效果。我这已经跑了,所以大家可以看一看这个相关的代码。

字体

接下来我们讲完标题扩展,我们再讲一个非常重要的一个就是字体。字体是什么,为什么要讲,就感觉前面两个是一个布局,一个比较困难,感觉都比较重,字体感觉很小,其实字体它是很重要的,为什么呢?因为所有的图标现在都是这样,很多都是用字体来承载,如果你要做一个比较好的布局。你可能需要很多字体来支持,所以你字体怎么来自定义是很重要的一个环节,大家可以看一下,就是在MAUI 上字体的官方支持,其实是在他的一个入口文件。

直接看项目入口文件。这个文件里面有一个 ConfigureFonts,这里面可以自定义字体。可以看一下这个方法,就是第一个是文件名,第二个是就是别名,那我们看看字体文件放在哪里呢。字体文件是放在 MAUI 里面有一个 resource,resource 里面的所有的 Fonts,其实 MAUI 都做了一个映射,你直接就是把字体放在这里,然后在这里添加字体就可以了。使用的时候PPT上面有写到他其实有两种方式,第一种是使用字体的名称,第二种方式其实你可以使用字体的别名。

接下来我给大家演示一下如何将 FontawesomeUWP 来迁移到 MAUI 平台。这个 DEMO 已经迁移完了,然后大家来看一看怎么一步步操作。

这个是 FontAwesome.UWP,它其实是一个官方的仓库,我们来看看主要有两个文件,一个文件,第一个是 FrontAwesomeicon.cs,这个是干嘛的?就是所有的字体的 Unicode 字符集,这个文件基本上不用修改就可以直接用。然后比较重要的是这个 FontAwesome.cs 控件。 那我们要进到 MAUI 怎么做呢?我这里是把它切换到了支持用继承 Label, FontAwesomeFontFamily,这个我们在 UWP 里面它是一个类型, 因为刚才说了,这里直接用别名就可以了,所以用 string 就行。

我们来看一下这个控件怎么使用,我在这里面有个 Demo。运行起来看到的效果:一个是感叹号,一个是这个。随便再来几个符号,看看能不能行。

如果现在是用安卓来跑,所以给大家看看安卓的实现效果。

原生控件

那接下来最重要的事就是告诉大家如何来做一个原生的控件,MAUI 里面能够生成原生控件呢?它是要实现 Handle 以及 Effect 这两个体系,来实现不同平台的一个原生控件,对应的话如果要做这个,要对应创建不同平台的 Handler 和 Effect,这将是非常重要的。

接下来会给两个示例:

  1. 第一个示例就是我们用 Handler 实现一个 button。
  2. 第二个示例是我们用 Effect 来实现一个支持点击事件的 Button。Effect 本质是简化了控件的自定义。如果你用 Handler 来实现也是可以的,那意味着就是更轻量一点。

我们来看一下,就是这个示例是怎么做的。这个代码可能有点复杂。可能要稍微认真一点。

我们先看看第一个 Handler 示例,我们要自定义一个 CustomButton,这里我们先要实现一个 ICustomButton  接口。这个 Content 是什么呢?就是 Button 不是要附一个内容嘛?就是 Button 里面的字是什么,比如说点击我之类的,所以我在这里面加了一个属性。然后同时呢,我们需要这个 utton 呢,需要一个事件。因为你如果做一个 Button,你没有点击事件的话是不 OK 的,所以在这里呢,我们做一个接口,就是 SendClick,这个等会告诉大家干嘛用的。这个事件是点击事件的发送。

接下来我们看一下就是来创建一个 CustomButton 这个类,它要继承两个东西。第一个是 View,这个是一个 MAUI 的控件,同时来实现这个 ICustomButton 这个接口。这类也比较简单,就刚才介绍了, BindableProperty 属性要实现一个 Content。然后基本上下面就是 SendClick 这个事件,然后上面有个 EditorBrowsable 这个是干嘛用的?这个是告诉 XMAL 不要去显示这个属性,在 XMAL 的界面上,这个属性其实是没用的,这个属性是。然后发送这个 Click 事件,然后回调。如果你继续注册这个,那就会执行。这边就创建完了,但是刚才说的叫原生控件,然后就这么简单吗?

所有的原生控件,我们需要创造一个 CustomButtonHandler,这个是用来映射不同平台实现的一个重要环节,你可以看到这个 PropertyMapper 属性就是打印的不同平台,这里面用了一个 partial 这个关键词,它其实是一个分布类,大家应该就很清楚。分布类就是说你可以在不同的地方定义这个类,然后来组合它的实现。这里比较重要的一个地方就是这个 MaContent,就是你要映射这个 MapContent 在不同平台的一个实现,这就是这个 ICustomButton.Content。

而各个平台里面的Handler,以Windows为例,继承ViewHandler,实现ConnectHandler、DisconnectHandler、MapContent、CreatePlatformView这几个方法:

最后在MauiProgram里面配置下Handler:

这个button实现了Content属性和Click这个事件,大家可以看下下面这个演示:

接下来我们要介绍的示例就是 Effect 。我们这个示例要实现一个自定义事件的 Button。我们来看看具体如何实现。

第一步:是建立名为TouchRoutingEffect的Effect:

第二步:以Windows为例,创建基类  TouchHandler

第三步:创建TouchPlatformEffect

第四步:创建下EffectButton

第五步:最后再注册下effect,就大功告成了

第六步:现在这个button可以这么使用,这样就实现了一个点击有动效的Button

基本上你只要学会了这两个,就是 Handler 和 Effect,就能实现 MAUI 原生控件。

MAUI控件

原生控件其实你需要非常了解各个平台的一个实现,比较适合你们团队内部的一些比较高级的同学去做,就是因为它需要了解,比如安卓iOS一个底层,比如刚才说的两个事件,这个其实是需要你了解安卓里面的一个touch。以及iOS里面touch,不然写不了这个控件的安卓和iOS的版本。然后MAUI控件呢,我把它定义为说就是你已经写好了一个原生控件,这个原生控件其实是可扩展的,那么我们可以在原生控件的上层进行分装,然后实现一个就是只要你用MAUI的代码就可以实现了,不用去定义多平台的一个东西就可以了。

来看看我们现在要实现一个 ImageButton 该怎么做。这个 ImageButton 就是告诉你就是有三个状态,来实现Button在Normal、Disabled、Pressed情况下的不同展示。 这个里面的代码其实基本上就是 EffectButton 的继承,就是如果你在写原生控件,这个原生控件是可扩展的,就是 MAUI 可扩展,然后写一下这些属性,这些属性基本上就是的 MAUI 属性。其实就简单的一个属性,没有什么特别的定义,就主要为了绑定这个属性用。

这个就是我认为,就是 MAUI 控件上层的封装,不用去关心多平台,这个是比较方便。所以呢,这也非常强调写原生控件的能力。能不能让同学更好地封装这个控件。

另类玩法

将 AspNet 嵌入到这个桌面上,但是其实你在 MAUI 上,如果你去嵌入这个FrameworkReference 这个APP 其实不行的。

这里我抽取了Kestrel的核心代码,上传到了nuget,可以搜索Kestrel.Core进行安装,因为是旧版本Kestrel,使用比asp.net core稍微繁琐

在浏览器直接输入 localhost:8080/hi?switch=on  就可以控制MAUI应用的UI展示

答疑

第一个问题:这个不支持WIN7吗?

这个是不支持WIN7的,为什么呢?因为它是基于WinUI的,应该是要WIN10以上的版本才行。

 

第二个问题:MAUI 和 WPF 性能方面哪个更好呢?

这个方面我确实没有测试过,回回头测试一下跟大家来介绍。就是你要看实际上的使用嘛,就是MAUI 基本上是基于 WINUI 的,最新的都是在 WINUI上 再套一层来支持跨平台的,在Windows上用WINUI。所以你要看你的实现是用来干嘛的,如果你对 WPF 是很熟,而且你在Windows上用,又不希望去扩展别的方面的内容,就是你可以尝试用WPF。如果你又希望全平台支持,那你可以尝试用MAUI,当然成本也会比较高,因为它现在的控件不是很完备的,就需要开发很多底层的原生控件,这个可能也比较耗时间,所以你要看你自己的情况来定。性能上呢,可以我回头测试来来反馈给你,但是你如果要使用的话,可以就看自己的情况来定。

 

第三个问题:能谈一下MAUI的前景如何嘛?

就是我其实想了解一下,你说的前景是说就业前景还是什么样的前景?还是说这个技术的前景,就是现在的跨端呢,其实是非常就是流行,当然不一定是MAUI,就各个平台的跨端都非常流行的,跨端是一个趋势,为什么呢?因为最开始的时候就是大家安卓iOS都不会,现在其实安卓、iOS和WINDOWS10工程师都很饱和了,然后如果你要开发一个应用呢,其实公司更讲究的是提升效率。所以呢,基本上每个公司包括什么腾讯,百度啊,都在研究的一个方向,微软的 MAUI 其实推出来它是一个原生的控件来支持,像国内的厂基本上很多都在用。国内的很多厂基本上都是类似小程序那种方式。跨端它是一个趋势,可以去学习 MAUI。如果你说技术前景的话。我觉得也是值得去学一下,如果你是Windows的开发者,这个是我觉得如果像企业开发,如果开发一个代码就可以实现生成多套代码,多个平台的可用的,这个非常节约成本,所以我觉得还是不错的,可以关注。

而如果是就业前景,因为它这个是比较一个新的技术嘛,所以它并不是说现在已经有很多公司要用了,微软上个月才刚刚 Release,基本上要看一下未来,但如果你有接触到一些公司用,比如说像WPF 这样的开发的话,做一些企业信息化系统的话,我觉得后面他们这些系统肯定会往这个跨平台去转的。应该还是不错的。但现在看不出来,就要过一段时间。现在你去看这个MAUI的就业,可能就你自己看,因为这个技术我觉得还是值得学习的。

给TA打赏
共{{data.count}}人
人已打赏
.NET MAUIMicrosoft Build

里程碑事件丨.NET MAUI 正式发布

2022-6-7 15:46:07

.NET MAUI

.NET MAUI 中的性能改进

2022-6-13 18:01:10

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
今日签到
有新私信 私信列表
搜索