[MAUI程序设计] 用Handler实现自定义跨平台控件

今天来谈一谈MAUI跨平台技术的核心概念——跨平台控件。

无论是MAUI,Xamarin.Forms还是其它的跨平台技术,他们是多个不同平台功能的抽象层,利用通用的方法实现所谓“一次开发,处处运行”。

跨平台框架需要考虑通用方法在各平台的兼容,但由于各原生平台(官方将原生称为本机)功能的差异,可能不能满足特定平台的所有功能。

比如,众所周知,MAUI的手势识别器没有提供长按(LongPress)手势的识别, TapGestureRecognizer也仅仅是按下和抬起的识别,没有提供长按的识别。

这时候就需要开发者自己实现特定平台的功能,这就是自定义控件。

要想重写控件,或增强默认控件的功能或视觉效果,最基础的功能就是要拿到跨平台控件,和本机控件。

通过跨平台控件定义的属性传递到本机控件,在本机控件中响应和处理自定义属性的变化。达到自定义控件的目的。

接下来介绍在MAUI新增的特性:控制器(Handler),好用但知道的人不多 。

Handler

因为跨平台控件的实现由本机视图在每个平台上提供的,MAUI为每个控件创建了接口用于抽象控件。 实现这些接口的跨平台控件称为 虚拟视图。 处理程序 将这些虚拟视图映射到每个平台上的控件,这些控件称为 本机视图

在VisualElement中的Handler对象是一个实现了IElementHandler接口的类,通过它可以访问 虚拟视图和 本机视图

public interface IViewHandler : IElementHandler
{bool HasContainer { get; set; }object? ContainerView { get; }IView? VirtualView { get; }Size GetDesiredSize(double widthConstraint, double heightConstraint);void PlatformArrange(Rect frame);
}

每个控件有各自的Handler以及接口,请查看官方文档。

它可以通过注册全局的映射器,作为特定本机平台上实现自定义控件的功能的入口。
然后结合.NET 6 条件编译的语言特性,可以更加方便在但文件上,为每个平台编写自定义处理程序。

Entry是实现IEntry接口的单行文本输入控件,它对应的Handler是EntryHandler。

在这里插入图片描述

如果我们想要在Entry控件获取焦点时,自动全选文本。

  Microsoft.Maui.Handlers.EntryHandler.Mapper.AppendToMapping("MyCustomization", (handler, view) =>{
#if ANDROIDhandler.PlatformView.SetSelectAllOnFocus(true);
#elif IOS || MACCATALYSThandler.PlatformView.EditingDidBegin += (s, e) =>{handler.PlatformView.PerformSelector(new ObjCRuntime.Selector("selectAll"), null, 0.0f);};
#elif WINDOWShandler.PlatformView.GotFocus += (s, e) =>{handler.PlatformView.SelectAll();};
#endif});

或者,可以使用分部类将代码组织到特定于平台的文件夹和文件中。 有关条件编译的详细信息,请参考官方文档。

与Xamarin.Forms实现的区别

在Xamarin.Forms时代,已经提供了一套自定义控件的机制,呈现器(Renderer)。

Xamarin.Forms的控件,比如Entry是通过在封装于特定平台下的EntryRenderer的类中渲染的。

在这里插入图片描述

通过重写控件默认Renderer,可以完全改变控件的外观和行为方式。

  • Element,Xamarin.Forms 元素
  • Control,本机视图、小组件或控件对象

为什么要用Handler代替Renderer

虽然Renderer功能非常强大,但是绝大部分场景来说,不是每次都需要重写控件,而仅仅是给控件添加一些特定平台的增强功能,如果还需要重写OnElementPropertyChanged 将跨平台控件的属性值传输到本机控件,这种方式太过于复杂。

以我的理解,Handler是对Renderer的一种优化,它解决了Renderer的这些问题:Renderer和跨平台控件的耦合,对自定义控件的生命周期管理,和对自定义控件的更细粒度控制。

解耦

在Xamarin.Froms的Render中,要想拿到跨平台控件的属性,需要通过直接引用跨平台类型,这样就导致了Renderer和跨平台控件的耦合。

在MAUI中,处理程序会将平台控件与框架分离。平台控件只需处理框架的需求。这样的好处是处理程序也适用于其他框架(如 Comet 和 Fabulous)重复使用。

生命周期管理

可以通过处理程序的映射器(Mapper)在应用中的任意位置进行处理程序自定义。 自定义处理程序后,它将影响在应用中任意位置的该类型所有控件。

可以通过控件HandlerChanged 和HandlerChanging,管理Handler的生命周期,通过其参数可以获取控件挂载、移除Handler的时机,可以在这里做一些初始化和清理工作。

更细粒度的控制

因为实现了全局映射器注册,这样的好处还有不用重写子类控件,我们可以通过获取跨平台控件的某属性,或注解属性,拿到需要进行处理的控件。实现自由的面向切面的过滤。

用Effect来实现呢?

或者我们仅仅想更改控件外观,可以通过Effect来实现。但无论是Effect还是Renderer,他们只能是全局的,在需要状态维护的业务逻辑中,比如长按,实际上是按下,抬起的过程,没有按下的控件不要响应抬起,正因为这样要记录哪些控件已经按下,可能需要用一个字典维护所有的自定义控件。

而MAUI的自定义映射器实际上就是一个字典,减少了代码的复杂度。

在MAUI中,官方建议迁移到Handler。Renderer虽仍然可以在MAUI中使用

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/147488.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

ffmpeg、ffplay在线安装,离线导出整个程序,移植到其他服务器使用(linux系统)

环境说明 以ubuntu系统作为说明 在线安装 下面命令会同时安装ffplay和ffmpeg sudo apt-get install ffmpeg怎么验证安装成功? 输入ffmpeg命令 ffmpeg,如图则说明安装成功 转储可执行程序和依赖的文件 找到安装路径,一般在/usr/bin目录…

C++标准模板(STL)- 类型支持 (std::size_t,std::ptrdiff_t,std::nullptr_t)

对象、引用、函数&#xff08;包括函数模板特化&#xff09;和表达式具有称为类型的性质&#xff0c;它限制了对这些实体所容许的操作&#xff0c;并给原本寻常的位序列提供了语义含义。 附加性基本类型及宏 sizeof 运算符返回的无符号整数类型 std::size_t 定义于头文件 <…

电脑显示系统错误怎么办?

有时我们在开机时会发现电脑无法开机&#xff0c;并显示系统错误&#xff0c;那么这该怎么办呢&#xff1f;下面我们就一起来了解一下。 方法1. 替换SAM文件解决问题 1. 重启电脑并进入安全模式。 Win8/10系统&#xff1a;在启动电脑看到Windows标志时&#xff0c;长按电源键…

机器人中的数值优化(二十)——函数的光滑化技巧

本系列文章主要是我在学习《数值优化》过程中的一些笔记和相关思考&#xff0c;主要的学习资料是深蓝学院的课程《机器人中的数值优化》和高立编著的《数值最优化方法》等&#xff0c;本系列文章篇数较多&#xff0c;不定期更新&#xff0c;上半部分介绍无约束优化&#xff0c;…

大数据Flink(九十五):DML:Window TopN

文章目录 DML:Window TopN DML:Window TopN Window TopN 定义(支持 Streaming):Window TopN 是一种特殊的 TopN,它的返回结果是每一个窗口内的 N 个最小值或者最大值。 应用场景

zemax场曲/畸变图与网格畸变图

网格畸变是XY两个方向上的几何畸变&#xff0c;是不同视场实际像高与近轴像高的偏差。 垂轴放大率在整个视场范围内不能保持常数 当一个有畸变的光学系统对一个方形的网状物体成像时,若δy>0&#xff0c;则主光线的交点高度y比理想像高y低,视场越大&#xff0c;低得越多&a…

Apache Derby的使用

Apache Derby是关系型数据库&#xff0c;可以嵌入式方式运行&#xff0c;也可以独立运行&#xff0c;当使用嵌入式方式运行时常用于单元测试&#xff0c;本篇我们就使用单元测试来探索Apache Derby的使用 一、使用IDEA创建Maven项目 打开IDEA创建Maven项目&#xff0c;这里我…

ESP32设备驱动-OLED-SSD1306(I2C)显示屏驱动

OLED-SSD1306(I2C)显示屏驱动 1、OLED介绍 OLED显示屏是指有机电激发光二极管(OrganicLight-EmittingDiode,OLED)由于同时具备自发光,不需背光源、对比度高、厚度薄、视角广、反应速度快、可用于挠曲性面板、使用温度范围广、构造及制程较简单等优异之特性,被认为是下一…

Vue3切换路由白屏刷新后才显示页面内容

问题所在&#xff1a; 1.首先检查页面路由以及页面路径配置是否配置错误。 2.如果页面刷新可以出来那证明不是配置的问题&#xff0c;其次检查是否在根组件标签最外层包含了个最大的div盒子包裹内容。&#xff08;一般vue3是可以不使用div盒子包裹的&#xff09; 3.最后如果…

无线WIFI工业路由器可用于楼宇自动化

钡铼4G工业路由器支持BACnet MS/TP协议。BACnet MS/TP协议是一种用于工业自动化的开放式通信协议&#xff0c;被广泛应用于楼宇自动化、照明控制、能源管理等领域。通过钡铼4G工业路由器的支持&#xff0c;可以使设备间实现高速、可靠的数据传输&#xff0c;提高自动化水平。 钡…

ARMday2

1~100累加 代码 .text .globl _start _start:mov r0, #1 fun:cmp r0,#100addls r1,r1,r0addls r0,r0,#1b fun .end运行结果

macOS 14 Sonoma 如何删除不需要的 4k 动态壁纸

概览 在升级到 macOS 14&#xff08;Sonoma&#xff09;之后&#xff0c;小伙伴们惊喜发现  提供了诸多高清&#xff08;4k&#xff09;动态壁纸的支持。 现在&#xff0c;从锁屏到解锁进入桌面动态到静态的切换一气呵成、无比丝滑。 壁纸显现可谓是有了“天水相连为一色&…

list(链表)

文章目录 功能迭代器的分类sort函数&#xff08;排序&#xff09;merage&#xff08;归并&#xff09;unique(去重&#xff09;removesplice&#xff08;转移&#xff09; 功能 这里没有“[]"的实现&#xff1b;原因&#xff1a;实现较麻烦&#xff1b;这里使用迭代器来实…

c语言 - 实现每隔1秒向文件中写入当前系统时间

实现思路 主要是通过库函数和结构体获取当前系统时间&#xff08;年月日和时分秒&#xff09;保存到变量里&#xff0c;然后通过格式化输出函数将当前系统时间输出到文件中去。 但是需要注意的是题目要求每隔 1 s对系统时间进行输出&#xff0c;所以需要加入 sleep()函数进行调…

设计模式10、外观模式Facade

解释说明&#xff1a;外观模式&#xff08;Facade Pattern&#xff09;又称为门面模式&#xff0c;属于结构型模式 Faade 为子系统中的一组接口提供了一个统一的高层接口&#xff0c;该接口使得子系统更加容易使用 外观&#xff08;Facade)角色&#xff1a;为多个子系统对外提供…

学信息系统项目管理师第4版系列15_资源管理基础

1. 项目资源 1.1. 实物资源 1.1.1. 着眼于以有效和高效的方式&#xff0c;分配和使用完成项目所需的实物资源 1.1.2. 包括设备、材料、设施和基础设施 1.2. 团队资源 1.2.1. 人力资源 1.2.2. 包含了技能和能力要求 2. 人力资源管理 2.1. 不仅是组织中最重要的资源之一&…

科技资讯|AirPods Pro基于定位控制的自适应音频功能

在接受 TechCrunch 媒体采访时&#xff0c;苹果高管 Ron Huang 和 Eric Treski 谈到了关于 AirPods Pro 自适应音频&#xff08;Adaptive Audio&#xff09;功能的轶事&#xff0c;曾考虑基于 GPS 信号来控制自适应音频级别。 Treski 表示在探索自适应音频功能初期&#xff0…

【C++进阶之路】C++11(上)

文章目录 一、列表初始化1.{}2.initializer_list 二、声明1.auto2.deltype 三、右值与左值1.基本概念2.应用场景1.左值引用2.右值引用3.完美转发4.万能引用 四、新增默认成员函数五、lambda表达式1.基本语法1.1捕捉列表1.2参数列表1.3返回类型1.4函数体 2.底层原理 总结 一、列…

【Redis】五大数据类型 、历史概述、nosql分类

文章目录 NoSql概述NoSql年代缓存 Memcached MySQL垂直拆分&#xff08;读写分离&#xff09;分库分表水平拆分Mysql集群最近为什么要用 NoSqlNoSql的四大分类 Redis测试性能 五大数据类型keyStringSetHashZset 前言&#xff1a;本文为看狂神视频记录的笔记 NoSql概述 NoSql年…

nodejs开发环境搭建

Nodejs是一个开源的、跨平台JavaScript运行时环境&#xff0c;其使用V8引擎对JavaScript脚本执行解释&#xff0c;在前后端分离的应用架构设计中&#xff0c;其既能支持web页面服务应用的开发、也能支持后端接口服务应用的开发&#xff0c;类似于Java语言的J2EE运行时环境&…