一些【控制面板】的界面设计中常常需要根据客户现场的不同环境来【动态定制】控制对象,定制对象的主体是界面与功能。对于界面而言,不同的需求需要显示的东西是不同的,布局、语言这些也可能有所改变。这样的需求意味着我们可能需要对界面进行动态配置,根据配置参数来生成不同的界面。
讲到这里就不得不面对下面几个问题,这里我以 awtk 为例,讲讲这种功能实现的一种思路,仅供参考!
1. 配置参数从哪里获取?
在 pc 端,配置参数常常可以使用【文件】为媒介,通过在程序中【读取文件】,【解析参数】来实现。如果要实现远程配置,那么可能需要用到【网络】,配置参数可以通过网络来分发到程序中。
对于嵌入式设备而言,通过文件配置程序这样的方式不容易实现。一些设备上可能根本不能使用 sd 卡,这让文件配置的方法无法实现。既然不能通过文件来配置,那有没有其它方式呢?
这里我先不回答这个问题。我想进一步的分析所谓的配置到底需要怎样的过程。无论从文件读取、从网络读取,这些不同的方式都是参数来源的不同,暂时抛开这些来源的不同,进一步的分析后面的配置过程可能会给我们一些启示!
从程序收到配置数据开始分析。收到数据后程序可能需要对数据进行【校验】,校验无误后可能会转入【解析数据】的流程,解析数据完成后将这些数据传递给一个动态生成界面的【黑盒】(在这里我暂且称这样的过程为黑盒),这个【黑盒】通过执行内部的代码就能够生成界面。
从上面的分析中我着重强调了配置数据的【正确性】与解析数据的【必要性】。
为什么要强调数据的正确性呢?
你想想我们依赖这些配置数据来生成界面,如果这些数据本身的正确性都不能得到保证,那么我们怎么保证最终生成的界面能够真的按照我们的预期工作呢?
至于【解析数据】这当然也是需要的!虽然上面使用了黑盒掩盖了生成界面的实际过程,可是黑盒固定了我们传递给它的参数格式,我们需要按照黑盒的规定来将参数从配置数据中提取出来并进一步处理,这样才能够让黑盒正常工作!
写到这里我们再次回到上面的问题——配置参数从哪里获取呢? 你可以发现我上面的描述中完全将配置参数的获取【忽略】了,实际上对于这点我【有意为之】。我想说明的是配置参数从哪里获取【不是】个难题,串口、网络都可以用来传递配置参数,其它的传输协议其实也能够达成相应的目的,只是可能不太容易与 pc 端对接!
当我们解决了配置参数获取的问题之后,我们需要考虑上面提到的那个黑盒该怎样实现?这里我提供两个方案仅供参考。
1. 完全使用代码生成界面
这样的方式是很容易想到的,不过是否要采用这样的方式还需要看具体的项目需求。如果项目中不同功能对应的界面没有统一的风格,那么就需要使用这种方式来完成了。
2. 代码与静态页面描述的结合
一个 gui 项目中界面的显示一般都符合【统一的风格】,这种统一【降低】了界面设计的复杂性,也在一定程度上【减轻】了动态生成界面的压力。
对于这种方式,一般的思路是我们可以将不同的功能模块化,以一类功能来组织页面。
每一类功能拥有自己的单独页面,同时提供一个导航页来注册每一类功能到主页中。这里我们可以把这一类功能看做是一个单独的应用程序,主页看做是进入这些应用程序的入口。这样我们会发现这里的过程与手机里面安装软件的过程有部分相似之处。一个软件安装成功后会在桌面生成一个图标,点击这个图标就可以进入应用程序,类似的一类功能的定制之后就在导航页生成一个图标,点击这个图标就能够进入功能页。
这里每一类功能的页面可以设计为【静态页面】,导航页可以使用代码来生成并建立跳转到功能页的”链路“!
那么在 awtk 中这样的方式该如何实现呢?
在 awtk 中,不同的功能可以设计为不同的 view,每一种 view 都可以指定不同的布局方式。然后根据配置来将多个 view 加载并组织为 slide_view 的子控件,并使用代码来生成导航页的界面并注册跳转到功能页的回调函数。
awtk 的布局功能十分强大,可以通过 child_layout 来为不同的 view 指定不同的布局格式!同时注意 awtk 也提供了加载单个控件而非整个页面的函数,这个函数是——ui_loader_load_widget。
本文从实际项目中动态配置页面的需求开始描述,以 awtk 为平台描述了一种解决方案,虽然依赖于 awtk ,但是其中的思考过程与需要解决的问题在不同的 gui 中也是相同的!希望更能够给需要要的朋友提供参考!