简介:TMS FMX UI Pack v3.7.7.5 是一套面向 Delphi 开发者的跨平台 UI 组件库,基于 FireMonkey 框架深度优化,尤其适合需要兼顾 Windows、macOS 与 Android 的应用界面开发场景。完整源码版提供超过 450 个组件,从基础控件到图表、日历等复杂功能模块一应俱全,开发者可查看并修改底层源码,按项目需求灵活定制控件行为和视觉风格,也便于在 Delphi 11 环境下进行性能优化与问题排查。压缩包采用 RAR 格式,整体约 56.74MB,内容围绕组件的源单元、示例工程及说明文档组织,安装和引用后可快速融入现有项目。目前已有 269 人学习使用,适用于希望减少重复 UI 搭建工作、打造专业一致界面效果的中高级 Delphi 移动与桌面应用开发者。 Delphi开发圈子里,TMS的组件包基本属于“绕不开”的存在。我最早接触TMS是从VCL时代的TAdvStringGrid开始的,后来项目全面转向FMX跨平台后,TMS FMX UI Pack就成了我工具箱里的常驻成员。这两天在整理旧项目时正好翻到了v3.7.7.5这个版本的完整源码包,结合近几年在Windows、macOS、Android三端实战中踩过的坑和积累的经验,写一篇完整的使用总结。如果你是正在做FMX跨平台开发、又被原生控件丑到怀疑人生的朋友,这篇文章应该能帮你省下不少调研时间。
从Delphi 10.3开始,FMX框架已经相当成熟,但官方自带的控件库在UI表现力上一直比较“素”。TMS FMX UI Pack的出现,本质上就是把这层短板补齐——它提供了几十个高质量的可视化组件,从数据表格、图表、日历到侧边栏、卡片、按钮,几乎覆盖了企业级应用UI的绝大多数场景。v3.7.7.5这个版本在这条产品线里算是一个相当稳定的迭代,兼容性、性能优化和组件丰富度都处于平衡状态。对于“full source”这个关键词,很多人可能理解成“白嫖版”,其实不是——TMS官方一直是提供Full Source授权方式的,购买后你能拿到完整的.pas源码,这对于需要深度定制控件行为、或者有安全审计需求的团队来说,价值远大于单纯的“能编译过”。
1. 为什么我最终选择了TMS FMX UI Pack
1.1 从一次真实项目选型说起
去年接手了一个进销存管理的跨平台项目,需求方要求Windows PC端和Android平板端共用一套业务逻辑代码,UI层面尽量保持一致。当时摆在我面前的选择其实不少:FMX原生控件、TMS FMX UI Pack、Delphi自带的Style适配、或者干脆针对两端各写一套界面。
我试着用原生FMX控件搭原型,只做了主界面和两个二级页面,效果说实话有点“简陋过头”——不是因为功能不行,而是控件的视觉层次感不够,数据表格的美观度和交互流畅性都达不到客户的预期。对比之下,TMS FMX UI Pack的TMS FMX Grid在视觉表现和功能完整度上几乎是无缝替代原生TGrid的最佳选择,尤其是虚拟滚动、混合行类型、单元格内嵌控件这些细节,省下来的工作量是肉眼可见的。
1.2 全源码版本的价值到底在哪里
我个人的建议是:只要预算允许,优先选择Full Source授权。原因很简单——你买的不是“能用的控件”,而是“能改的控件”。
举个实际例子:TMS FMX Grid默认的排序指示器样式是箭头,但客户要求在平板端换成“升序/降序+颜色区分”的组合样式。如果是编译版组件,这件事基本无解,你只能通过事件二次绘制来做间接实现,代码绕且不清爽。有了源码就不一样了,直接找到SortIndicator的绘制方法,改掉默认行为,重新编译安装即可,后续维护也完全可控。
另外,full source在调试时也有巨大优势:你可以直接进入组件源码内部设置断点,查看绘制逻辑和数据绑定流程。运营阶段若遇到偶发的列表闪烁问题,顺着源码排查效率远高于黑盒调试。
1.3 组件覆盖范围速览
v3.7.7.5的组件数量相当可观。按照我日常使用的频率来划分,大致有几类:
- 数据展示类:TMS FMX Grid、TMS FMX TreeView、TMS FMX ListView
- 图表可视化:TMS FMX Chart、TMS FMX SparkChart
- 输入与交互:TMS FMX Edit、TMS FMX ComboBox、TMS FMX DateTimePicker
- 布局与导航:TMS FMX Sidebar、TMS FMX CardPanel、TMS FMX TabControl
- 系统集成:TMS FMX Localization、TMS FMX InAppPurchase
其中Grid和Chart是我项目中的绝对主力,后面会专门展开讲。
2. 环境准备与安装避坑指南
2.1 版本兼容性核对
先强调一个原则:不管是什么组件包,安装前一定要核对IDE版本和组件版本之间的兼容关系。TMS FMX UI Pack v3.7.7.5官方支持的是RAD Studio 10.3 Rio到11.x Alexandria这代产品,具体的版本号在安装包内的README或者TMS官网的Compatibility Matrix里都有明确标注。
我当时踩过的一个坑是:刚开始在一台装着Delphi 10.2 Tokyo的机器上直接安装,结果编译报了一大堆“Unit not found”的错误,排查后才发现是IDE版本太老,某些FMX框架内部接口对不上。后来升级到10.3.3,一次通过。
注意:如果你还在用10.2或更早版本的Delphi,我的建议是优先升级IDE,而不是降级组件版本。老版本IDE + 新组件包的兼容性风险远大于新IDE带来的系统资源开销。
2.2 安装全过程与常见编译错误
TMS FMX UI Pack的安装比较传统:从官网下载安装包(Full Source版本会额外附带Source目录),运行后选择对应的IDE版本(32位或64位按需处理),然后等待编译安装。
不过很多人在这步容易栽跟头。安装包默认使用的是当前IDE的默认编译器配置,如果在此之前你手动调整过Library路径或者安装了其他第三方组件,可能会出现重复单元定义或路径优先级冲突。
解决思路是这样的:先在IDE的Tools > Options > Language > Delphi > Library中,把默认的Library路径检查一遍,确认没有残留的旧版本TMS路径。然后把安装包提供的Source路径添加进来,并且确保这个路径排在Library列表的靠前位置。
安装完成后务必验证一下:新建一个空白FMX项目,随便拖一个TMS FMX Grid到窗体上,编译运行。如果这一步稳定通过,说明安装基本没问题。
2.3 全版本共存的策略
很多团队会同时维护多个版本的Delphi IDE,也会用到多个版本的TMS组件。我给自己的环境定了三条规则,实测下来非常管用:
- 每个IDE版本单独安装一份TMS组件,路径互不混淆
- 源码包放独立目录,不塞进IDE安装目录内
- 更新组件版本前先备份当前可用的Library路径配置
尤其是第三条,TMS经常在不同小版本间调整内部接口,回退版本时需要把旧版本的Source路径恢复回去,没有备份就只能靠记忆去填,非常折腾。
3. 核心组件深度实战
3.1 TMS FMX Grid:从基本绑定到高级应用
TMS FMX Grid是我用得最重的组件,没有之一。它本质上是一个高性能的虚拟化表格组件,支持本地数据绑定、主从架构、行/列自由合并、单元格内嵌进度条、图片和按钮等。
基础使用方式非常直接。假设你有一个TFDMemTable作为数据源,只需要指定Grid的DataSource属性,表格就会自动拉取数据并渲染。普通程序员到这一步就可以“交差”了,但实际项目里,我们通常还要处理列宽自适应、行高按内容伸缩、冻结列、横向滚动吸底这些细节。
我在做仓储管理界面时,遇到过一个问题:表格列数多达14列,在平板横屏下依然需要横向滚动。TMS FMX Grid的列冻结功能完美解决了这个问题,把“商品名称”“条码”这类关键列设置成冻结状态,用户滚动时它们始终保持可见,体验提升很明显。
设置方式:在列集合中找到需要冻结的列,把它的Frozen属性设为True,然后指定FrozenColumnsCount。源码版本中你甚至可以自定义冻结列和普通列之间的分界线样式。
另一个非常实用的功能是“可编辑单元格”。直接在Grid上启用Editing属性,再配合TMS FMX Edit作为默认编辑器,用户就能在表格内直接修改数据,修改完成后通过OnCellEditingDone事件回调进行数据校验和保存。我实际测试过,在1000行数据规模的界面中,编辑操作几乎无卡顿。
3.2 图表组件:TMS FMX Chart的定制思维
Chart组件在进销存里也是高频刚需,尤其是近30天销售趋势、品类占比这类分析图。TMS FMX Chart的API设计比Delphi自带的TChart要清爽不少,它提供了一套FMX原生的可绘制模型,性能好,跨平台表现一致。
基础的折线图,三行代码搞定:
var series: TMSChartLineSeries; begin series := TMSChartLineSeries.Create(Self); series.Title := '销售额'; Chart1.AddSeries(series); series.AddXY(1, 1200); series.AddXY(2, 1480); series.AddXY(3, 1320); end;但真实项目里我们很少直接用硬编码数据,更多是绑定数据源。TMS FMX Chart支持从TDataSet或泛型列表加载数据,也支持动态添加多个Series做对比。我在做库存周转率对比页面时,一次性挂了5个Series、涉及2000多个数据点,图形渲染依然流畅。
配色方面,默认样式比较朴素。源码版本里可以直接改Series的Brush和Stroke属性,也可以在绘制事件中做更精细的颜色过渡。我自己常用的一个技巧是:给系列的数量动态生成一个“渐变色板”,避免两个系列颜色太接近导致图表难以阅读。
3.3 日历与日期选择:TMS FMX Calendar的降维打击
如果你做过酒店预订、排班管理或者任何涉及日期范围的业务,一定会对Picker类控件特别敏感。FMX自带的TDateEdit功能太基础,不支持范围选择,也无法自定义日期的视觉状态。
TMS FMX Calendar补齐了这些缺口。它支持的选择模式包括单日、多日、连续区间,也可以通过事件自定义某个日期是否可点击。我在这套组件上做排班系统时,把工作日、休息日、节假日在日历上用不同颜色标记出来,直接给用户一个直观的“可排班/不可排班”视觉反馈。这种细节用原生控件实现起来非常痛苦,用到TMS Calendar只需要处理对应的事件回调即可。
在Android端实际使用的过程中,TMS FMX Calendar的触控体验也表现得不错——滑动切换月份、多点缩放,这些交互都有基础支持,未做额外定制的情况下已经能提供接近原生应用的流畅度。
4. 跨平台部署中的关键问题排查
4.1 Android端中文字体渲染问题
FMX在Android端的中文字体渲染一直是个敏感话题。使用TMS FMX Grid和Chart时,如果字体设置不当,会出现中文显示为“豆腐块”或者锯齿明显的问题。
我的解决方案是在程序启动时全局设置一次字体:
TFontManager.SetDefaultFont('MiSans');MiSans或者HarmonyOS Sans这类字体文件打包进Assets中,程序启动时加载。实测下来,在Android 8以上版本的中文显示效果非常干净利落。如果你更看重字节数控制,也可以继续使用系统默认字体,但在部分国产ROM上会出现某些控件字体不一致的问题。
注意:务必在Application.Initialize之后、MainForm创建之前调用全局字体设置,否则会有部分控件已经初始化了错误的字体引用,导致后续切换不彻底。
4.2 Windows缩放DPI下的布局错乱
Win10/Win11系统下,FMX应用在高DPI缩放下偶尔会出现布局错乱的现象,TMS FMX UI Pack本身对高分屏适配做得不错,但如果你混用了原生FMX控件和TMS控件,就可能出现“比例不协调”的问题。
排查思路是:检查主窗体的Font.Size是否设置得过大,以及TMS控件是否显式指定了Width/Height。在高DPI模式下,控件的物理像素和逻辑像素比例会变化,如果某些控件用固定像素硬编码,缩放时就会露馅。
我通常的做法是对所有主界面控件采用Align=Client或Align=Top/Left配合Margins自适应,避免使用绝对定位。这一习惯在跨平台部署时能省掉80%的布局调整工作。
4.3 编译包体积与启动性能优化
Full Source版本组件编译进EXE后,包体一般会比编译版大一些,因为核心代码是以静态链接方式进入可执行文件的。对于Windows桌面端来说,这不是问题;但Android APK的包体膨胀就会影响用户下载转化率。
我的优化实践是使用RTTI裁剪配合代码混淆,实际上TMS FMX UI Pack的组件单元只会在你引用到相应单元时才被链接,所以不必太过恐慌。但有一点警惕:在DUnitX单元测试项目里如果调用了整个组件包的所有单元,最后Build出来的测试APK可能会超过100MB。这种情况需要手动隔离测试项目与主业务项目的单元引用范围。
5. 源码级定制:那些常规文档不会告诉你的技巧
5.1 如何安全地修改组件源码
前面提到过full source的一大价值就是可以深度定制。但这里我必须要给一个诚恳的建议:不要轻易改动源码包里的公共接口,尤其是public和published方法签名。一旦改动,后续升级组件版本时,合并成本会非常痛苦。
更稳妥的做法是:通过继承来扩展。比如TMS FMX Grid,你完全可以写一个TMyGrid继承TMSFMXGrid,在子类中重写需要修改的virtual方法,或者增加新的属性和事件。这样既满足了定制需求,又保住了源码的纯净性,未来还能顺畅升级组件版本。
我自己的组件库中,就长期维护着基于TMS FMX Grid扩展的TGridEx、基于TMS FMX Chart扩展的TChartEx,这些扩展类沉淀了我对业务交互的理解和封装,复用到新项目时效率极高。
5.2 用拦截器(Interposer)做快速补丁
还有一种临时性的修改技巧,叫“拦截器类”——就是声明一个与原始类同名的新类,在单元引用顺序上让自己的类“覆盖”原类。这种方法适合快速验证某个修改方案是否可行,但因为风险较大,不建议在生产环境长期使用。
我这边的实践是:先用拦截器验证效果,确认改动思路没问题后,再决定是否升级成继承方案,或者将改动提交给TMS官方建议合并。保持克制和规范,才能在升级浪潮中持续稳定地使用组件。
5.3 主题定制与视觉统一
TMS FMX UI Pack本身支持通过TMS FMX Style进行主题定制。Full Source的好处是,你可以直接看到Style文件里绑定的每个资源名,比如“grid_cell_normal”、 “chart_series1_fill”这样的命名,改起来一目了然。
我花了一个下午,把整套组件包的主题色统一成了公司品牌色——深蓝+#FFA500点缀。做法并不复杂:用TMS提供的Style Editor(在Tools菜单里可以找到)加载默认Style,批量替换颜色值,保存后通过TStyleManager.SetStyle全局应用。关键点是替换颜色时要保持Opacity的一致,否则会出现“颜色对了但看起来怪怪的”情况。
5.4 与第三方FMX库的共存策略
现实项目里,几乎没人只用TMS一家组件库。你可能同时用了DevExpress的FMX控件、Grijjy的Foundation库或者ZXing的扫码组件。这些库之间是否会发生冲突?我实测下来,TMS FMX UI Pack的类名前缀大多是TMSFMX开头,命名空间隔离做得还算清晰,冲突概率很低。
唯一需要注意的是单元引用顺序。如果两个库都定义了同名的辅助函数或常量,链接时可能出现“Ambiguous overloaded call”的编译错误。解决方法是细化uses列表,尽量按需引用,避免在公共单元中粗暴地写“uses TMSFMXGrid, MyUtils;”这种大杂烩。
6. 总结与个人心得
兜兜转转用了几年,TMS FMX UI Pack v3.7.7.5在我的工具箱里一直保持着比较高的存在感。它让我在FMX框架下能做出让客户满意的界面,同时又不牺牲德尔菲开发者的高效率节奏。跨平台不只是把代码从一个平台搬到另一个平台,更重要的是让UI、交互和性能在每个平台上都不过时、不别扭。
最后分享一个我个人的工作习惯:每接手一个新版本TMS组件包,我先不看Release Notes,而是打开Demo源码,逐个运行官方示例,再对照源码看实现方式。这个过程往往比任何文档都更快地让我掌握组件的最佳实践。v3.7.7.5的Demo工程里,Grid和Chart相关的示例代码尤其精彩,有些高级用法至今我仍在翻阅。
如果你正在FMX跨平台项目里和数据表格、图表、日期选择做斗争,这套组件值得你花一个周末去试一下。在真正投入业务之前,把环境装好、把示例跑通、把源码结构摸清,后面的一切都会顺不少。
本文还有配套的精品资源,点击获取