UI2Code智能生成Flutter代码——机器生成代码

背景

在《UI2CODE--整体设计》篇中,我们提到UI2Code工程的整体流程。前步图片分析之后,我们可以得到对应的DSL布局描述。利用DSL的资讯,结合IntelliJ Plugin介面工具,面向使用者提供生成对应Flutter代码。

本篇主要介绍我们如何处理DSL的资讯,想法上即是Flutter的翻译机。总体概念如下:

输入的DSL是什么?

DSL做为一种描述语言,抽象表示为了解决某一类任务而专门设计的计算机语言。在此我们的DSL代表图像识别和布局识别侧的输出,为一JSON格式。

这些资讯主要描述了这个图层(Layer)的范围(Frame)、是什么样子的类型(Type)、是什么样子的样式(Styles)、含有哪些数据(Value)等等。图层集(Layers)栏位则代表了这张视觉稿的所有图层。

核心思路

本节的目标是将DSL翻译成目标的Flutter代码。我们首先需要理解的是分散的图层间的关系,可能会有交叠、可能是并列排版。知道了关系之后,需想办法转化成Flutter widget的视图,根据此视图来生产对应代码。

架构上我们把DSL tree和Flutter tree的建立,分拆为两个独立的分界。这样比较容易定义问题,并且保持弹性。如果今天的目标语言换成Weex或是iOS UI,我们就只需要更动代码翻译的模组。

第一把刀:DSL tree建立

上图的左侧代表了来源DSL的layers资料,代表者一个一个的图层。右侧是目标的DSL Tree,这棵树的结构上明确叙述了图层之间的包裹、交叠等关系。并且包含了某些特殊关系的节点聚合。

作法上利用每个Layer的Frame,以及所属的类别(文字、图像、容器),利用下面的规则组合树的关系:

  1. 图层之间的包裹关系,例如某些图层为容器,代表下面是可以挂其他节点的(这边带有背景属性的容器,我们定义称之为Shape
  2. 区块式组件(Block, 如ListView/GridView)。可以将图层组成View item的关系
  3. 闲鱼定义的组件资讯(如CI以及BI),这部份非闲鱼工程可以忽略
  4. 重复布局(Repeat)的资讯,将相同的图层归类合并,目的为简化树

根据以上我们采用了分层,由大至小的次序将Layer分群合并。另外,在合并时layer之间彼此可能有关联;它们可能同属于Block,也可能同属于某个Repeat。所以对于上面定义的Repeat、BI、Block、CI、Shape都可能有交错的嵌套关系,这是必须要处理的部份。

第二把刀:Flutter tree建立

在Flutter Tree的建构中,核心概念先处理布局。布局的概念如剥洋葱一般,我们先去除四周的padding,然后以人类视觉layout的直觉先尝试横切分,再进行竖切分

1.先剥洋葱去除padding

2.接著我们的算法会先尝试是否可以横切,如下图我们可以切割成为Row1/ Row2

3.针对Row1在尝试再进行竖切,如下图可以得到Column1/ Column2/ Column3

根据以上切分的规则,我们就可以定义出如Row、Column、Padding的几个节点,以及它们的Parent/ Child关系。将DSL tree同一层的节点做切分,一边切分一边建立Flutter node,遍历完整颗DSL,即可得到粗略的Flutter tree关系。

= 无法切分时的处理

当图层切分不开时,这时候就要使用绝对布局叠层的概念,这个概念在Flutter内称之为Stack。

多个图层在DSL tree的关系为兄弟节点,根据此些图层的Frame,我们判断出来它们是彼此相交的,我们会以Z-order概念,来决定上下交叠的关系。最后,这些图层将组成一个新Stack节点,并且产生此节点的Frames为此些图层覆盖的范围。

= 针对文字的进阶处理

基本上交叠的图层以Stack的处理就可以正确显示,但在文字图层上可能含有误区。

如上图因为文字本身的上下左右是含有padding的,在我们图层的识别时,可能会计算出彼此的frame是交叠的,但实际上UI希望它们并不是Stack关系。

 

为了解决这个问题,我们引入了一个oriFrame的概念,用文字最原始的像素当做是oriFrame。所以遇到为文字的图层时,我们会先判断本身的oriFrame是否交叠,如果是的话才采用Stack切割,否则就以此oriFrame对原始的frame做修正。

文字还有什么特性?

另外,因为文字的内容通常是动态的,所以拥有了”所见不一定为所得”的特性。这些特性主要包含了是否该换行、内容区域是否可以拉伸、文字Padding等,这些特性都会影响到我们的布局。

以下图为例,我们在处理Layout时肉眼很明显可以知道这些特徵。文字的行数我们可以以视觉稿当做最大显示范本,文字区域的宽度部分,则需要特别判断哪些区域是可以被拉伸的。

确立文字范围

在决定拉伸对象之前,我们需要定义哪些widget是将内容完整显示,不能被拉伸的:如图片、Container容器、Stack区域、Component组件

接著处理的流程如下:

  1. 首先判断所有Child内是否有多行文字或宽度固定的文字,如果是的话针对其处理。需要加上Flex。
  2. 若无以上的状况,则判断Child间的Padding关系
  3. 如果可拉伸的widget的Padding大于平均值的个数有多个,则这些都加上Flex
  4. 如果只有单个时,则找寻最大Padding的widget(使用分群拉伸算法)
  5. 最后,但当Row里面存有拉伸的状况时,需要把Row的最后一个child加上Right padding,否则拉伸元素会填满父容器。

分群拉伸算法:这个算法的目的是找到最佳拉伸的对象。我们的思考上将Widget做分组,分组后判断整体的Alignment(如左右对齐)或是拉伸关系。若在拉伸状况下,判断适合让哪个组别拉伸,在进一步判断适合让组别的内部元件拉伸。

举例如下为一个Row排列的控件,其中排列为Image、CI、Text1、Text2、Text3:

依据Widget之间的距离,在上图分为了Group1及Group2两个群体。先以Group1判断是否存在可拉伸的对象, 接著才判断Group2。所以这5个Widget分别得到了3, 2, 1, 4, 5的优先级。以本例而言,Text1为最高优先,而且其为可拉伸的,故决定将Flex属性加于此。

在Expanded的处理上,是我们目前遇到最大的困难点,甚至人工判断都可能有歧义。上面的规则是我们归纳出众多视觉稿的通解,但不能100%完全解决问题。所以这部份判断错误的部分,我们期待在Plugin的交互中使用人工解决。

= 判断Alignment优化

以上的处理已经可以正确生成Flutter tree,但是我们想进一步地将Flutter代码更加优雅。在此我们针对了三种元件的Alignment做了处理,分别是Container、Row、Column,其概念都是分析内部元件的padding关系,决定为居左、居中、或是居右对齐。

举例如Column内部的children我们去判断左右的padding是否相等。若是则移除其padding,并且加上crossAxisAlignment为center。

针对Row/ Container我们则会判断crossAxisAlignment(垂直方向)以及mainAxisAlignment(水平方向)。水平部份,这边我们采用更精细的方法,我们利用欧式距离建立一个非监督算法,计算views是更为接近哪一个(居左、居中、居右)。算法这边先不详述,之后再以篇幅介绍。

最后:生成Flutter代码

经过前面的步骤后,最终我们产生了一个Flutter Tree。生成时在节点的定义上,我们分为了两种,分别是View与Layout,以是否可以拥有Child为区别。以下是我们针对Flutter Tree所定义的部份类别:

在节点的定义中,皆存储了各节点的Parent、Child属性。根据这些关系,我们定义每个节点的代码样板,例如FColumn对应的样板为:

 


new Column(
#{alignment},
children: <Widget>[#{children},
]

), 

最后我们以Root widget开始遍历整颗树,将每个节点所生成的Flutter代码结合,这样我们就可以得到整个Widget tree的代码了。

数据分离

为了更好的重复利用生成代码,我们把生成的代码和数据再进一步做分离。分离后输出分为代码区以及Data model数据区:

我们切割这些区域的目的为简化Widget tree直观上的代码复杂度,以及将数据抽离,让资料可由外部呼叫传入,以达成动态性。

整体架构回顾

总合以上的概念,工程的细部架构如下:

前面所说的针对文字以及Alignment的处理,在这边我们设计了一个工厂模式,如上图中经过Flutter Tree Builder后,我们可以去遍历整颗Widget tree,在工厂中判断判断符合条件的规则,经过处理去震荡优化原本的Widget tree。在这边未来我们可以不断地加上合适的规则,让Widget tree更加优化。

整体架构使用静态分析的方法,读到此各位可能会有疑问:一些如动态的事件、View的Visibility、Input输入文字框等怎么处理?由于这些动态性在静态分析下无法解决,所以我们增强了Plugin上的编辑性,使用者只要勾选某些属性,即会在生成代码时自动判断,在Flutter自动增加对应的逻辑。以弥补静态图无法处理的问题。

由于UI的灵活性高,十个人写的代码可能有十种不同风格。并且在分析上游的UI2DSL,以及Flutter代码的翻译,某些部份的精确性取决于我们的样本的认知,是否能够在有限的样本内观查出泛化的定律,分析上还是存有很多挑战性。

结合落地业务

在整个UI2CODE的效果中,大约七成以上的页面都可以正确分析出来,剩下的是一些小细节如文字的处理等,基本上我们工具都能够将大框架的处理好,使用者可能只需微小的调整。

UI2CODE案子在内部团队上线后,已经在闲鱼APP内的"玩家页面"采用了自动化生成的代码。在采用自动化工具后,大约减少了三分之二的UI开发时间(因初期还在熟悉工作流程,未来相信可以更快速)。同时,若在客户端大量采用我们工具,还可以让团队的代码结构有一些的规范,让生成工具来规范Widget UI以及Data Binding的框架,一致性以及后续的维护,相信是一个很大的诱因。

并且闲鱼团队近期计画开发一款新的APP,在初期时能够快速开发UI,也将采用我们的工具。期望有更多的业务和经验积累。

后续计画

近期我们推出了第一版UI2CODE,先计画于内部团队使用,利用使用的经验,让我们在叠代之下不断提高准确性。并且,我们正在调研结合NLP以及AST(语法树)的可能性,希望能够产出更有质量的代码。

我们也期望未来能将此工具开放于Flutter community,对于推动整个Flutter技术有所推进。希望能让更多人跟我们一起找寻更有效率的写代码方法,如果有任何想法欢迎与我们交流,我们也持续不断地在进化工具中,谢谢各位的阅读!


原文链接
本文为云栖社区原创内容,未经允许不得转载。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

初始化java工具失败,“初始化 Java 工具”期间发生了内部错误, java.lang.NullPointerException...

今天刚打开eclipse就报了这个错误&#xff0c;我怀疑是昨晚想关电脑的时候&#xff0c;关闭eclipse太快&#xff0c;没有等待工作空间保存就关了电脑的缘故错误如图&#xff1a;(图片来自下方链接博客&#xff0c;因为忘记截图了) 我百度后按照提示&#xff0c;删除了eclipse工…

Node.js 应用故障排查手册 —— 正确打开 Chrome devtools

楔子 前面的预备章节中我们大致了解了如何在服务器上的 Node.js 应用出现问题时&#xff0c;从常规的错误日志、系统/进程指标以及兜底的核心转储这些角度来排查问题。这样就引出了下一个问题&#xff1a;我们知道进程的 CPU/Memory 高&#xff0c;或者拿到了进程 Crash 后的核…

钉钉流量暴增百倍,阿里云抗住了!

2月12日&#xff0c;钉钉已连续在苹果应用商店霸榜7天。记者采访获悉&#xff0c;春节以来&#xff0c;在家办公及在家上课的强需求&#xff0c;使得钉钉后台系统峰值流量暴增百倍。钉钉通过阿里云连续扩容10万台云服务器&#xff0c;成功抗住这一巨大的流量冲击&#xff01; 2…

PB 级数据处理挑战,Kubernetes如何助力基因分析?

引言 James Watson 和 Francis Crick 于 1953 年发现了 DNA 的双螺旋结构&#xff0c;从此揭开了物种进化和遗传的神秘面纱&#xff0c;开启了人类对数字化遗传的认知&#xff0c;但是人类基因奥秘却是一点点被读懂的。 1956 年&#xff0c;一则癌症和染色体相关性的发现令整…

Nginx 外的另一选择,轻量级开源 Web 服务器 Tengine 发布新版本

新版发布 近日&#xff0c;轻量级开源 Web 服务器 Tengine 发布了2.3.0版本&#xff0c;新增如下特性&#xff1a; ngx_http_proxy_connect_module [1] &#xff0c;该模块让 Tengine 可以用于正向代理场景&#xff0c;支持对 CONNECT 方法请求的处理&#xff1b;HTTP2 Serve…

腾讯云数据库Redis助力百万企业远程办公

受疫情影响&#xff0c;多数企业员工目前无法回到写字楼办公&#xff0c;学生推迟开学&#xff0c;稳定高效的远程办公和直播授课成为2020年的开年刚需。腾讯从1月24日开始向全国免费开放可支持300人同时在线会议的“腾讯会议”&#xff0c;直至疫情结束。央视新闻联播对此也给…

打通前后端逻辑,客户端Flutter代码一天上线

一、前沿 ​ 随着闲鱼的业务快速增长&#xff0c;运营类的需求也越来越多&#xff0c;其中不乏有很多界面修改或运营坑位的需求。闲鱼的版本现在是每2周一个版本&#xff0c;如何快速迭代产品&#xff0c;跳过窗口期来满足这些需求&#xff1f;另外&#xff0c;闲鱼客户端的包…

迈向电商认知智能时代的基石:阿里电商认知图谱揭秘

阿里妹导读&#xff1a;电商平台最大的挑战是从日益增长的海量商品&#xff08;数十亿&#xff09;中挑选出的一个小的子集&#xff08;几十或上百&#xff09;展示给用户&#xff0c;以满足用户的个性化的购物需求。为了解决仍存在的重复推荐、缺少新意等问题&#xff0c;我们…

我是如何用6个月,从0编程经验变成数据科学家的?

来源 | medium编译 | 武明利责编 | Carol出品 | CSDN云计算&#xff08;ID&#xff1a;CSDNcloud&#xff09;我叫Kate&#xff0c;刚从长达 8 年的学习和艰苦的工作中走出来&#xff0c;没有任何预兆。你可能想问&#xff0c;为什么有人会这么做&#xff1f;不得不说&#xff…

Node.js 应用故障排查手册 —— 综合性 GC 问题和优化

楔子 本章前面两节生产案例分别侧重于单一的 CPU 高和单一的内存问题&#xff0c;我们也给大家详细展示了问题的定位排查过程&#xff0c;那么实际上还有一类相对更复杂的场景——它本质上是 V8 引擎的 GC 引发的问题。 简单的给大家介绍下什么是 GC&#xff0c;GC 实际上是语…

“龙井”开箱评测 |Alibaba Dragonwell 新手上路指南

阿里巴巴有着最丰富的 Java 应用场景&#xff0c;覆盖电商&#xff0c;金融&#xff0c;物流等众多领域&#xff0c;是世界上最大的 Java 用户之一。 2019 年 3 月 21 日&#xff0c;阿里巴巴在北京阿里云峰会上正式宣布开源了 Alibaba Dragonwell 8 产品&#xff0c;并建立了 …

基于角色的访问控制(RBAC)

来源 | 编程新说责编 | Carol出品 | CSDN云计算&#xff08;ID&#xff1a;CSDNcloud&#xff09;很多时候&#xff0c;需要对一些事物进行控制&#xff0c;如一个房间&#xff0c;为了不让人随便进&#xff0c;通常会装一把锁&#xff0c;如果要想进入&#xff0c;你必须得有一…

win10 ie中没有java,win10没有ie浏览器怎么处理_window10找不到ie浏览器如何解决

很多用户升级到win10系统之后&#xff0c;发现默认浏览器是edge&#xff0c;想要使用ie浏览器的时候却发现没有ie浏览器&#xff0c;遇到window10找不到ie浏览器的话该怎么办呢&#xff0c;下面随小编一起来看看详细的解决步骤吧。方案一&#xff1a;1、直接搜索&#xff0c;右…

手把手教程:用Python开发一个自然语言处理模型,并用Flask进行部署

截住到目前为止&#xff0c;我们已经开发了许多机器学习模型&#xff0c;对测试数据进行了数值预测&#xff0c;并测试了结果。实际上&#xff0c;生成预测只是机器学习项目的一部分&#xff0c;尽管它是我认为最重要的部分。今天我们来创建一个用于文档分类、垃圾过滤的自然语…

干货|Spring Cloud Stream 体系及原理介绍

Spring Cloud Stream 在 Spring Cloud 体系内用于构建高度可扩展的基于事件驱动的微服务&#xff0c;其目的是为了简化消息在 Spring Cloud 应用程序中的开发。Spring Cloud Stream (后面以 SCS 代替 Spring Cloud Stream) 本身内容很多&#xff0c;而且它还有很多外部的依赖&a…

阿里小程序云应用上线了,有哪些看点?

3月21日&#xff0c;在2019阿里云峰会北京上&#xff0c;阿里巴巴旗下的阿里云、支付宝、淘宝、钉钉、高德等联合发布“阿里巴巴小程序繁星计划”&#xff1a;提供20亿元补贴&#xff0c;扶持200万小程序开发者、100万商家。凡入选“超星”的小程序&#xff0c;入驻支付宝、淘宝…

10 个实用功能告诉你,谷歌云(Google Cloud)相对亚马逊云(AWS)有哪些优势?...

来源 | itnext编译 | 武明利责编 | Carol出品 | CSDN云计算&#xff08;ID&#xff1a;CSDNcloud&#xff09;有很多文章将谷歌云提供商&#xff08;GCP&#xff09;与亚马逊云服务&#xff08;AWS&#xff09;进行比较&#xff0c;但这篇文章并不想要做比较。作者主要是一个AW…

mybatis-plus大批量数据插入缓慢问题

文章目录问题排查结果建议问题 最近项目用的mybatis-plus做的映射&#xff0c;有个批处理文件内容的需求&#xff0c;在使用mybatis-plus的批处理方法saveBatch时发现速度特别慢&#xff0c;测试从1000到10000到80000条基本上是线性增加&#xff0c;80000条时差不多要90秒。 …

世界冠军之路:菜鸟车辆路径规划求解引擎研发历程

阿里妹导读&#xff1a;车辆路径规划问题&#xff08;Vehicle Routing Problem, VRP&#xff09;是物流领域最经典的优化问题之一&#xff0c;具有极大的学术研究意义和实际应用价值。菜鸟网络高级算法专家胡浩源带领仓配智能化算法团队经过两年的研发&#xff0c;逐步沉淀出了…

原来,阿里工程师才是隐藏的“修图高手”!

阿里妹导读&#xff1a;在现实世界中&#xff0c;信息通常以不同的模态同时出现。这里提到的模态主要指信息的来源或者形式。例如在淘宝场景中&#xff0c;每个商品通常包含标题、商品短视频、主图、附图、各种商品属性&#xff08;类目&#xff0c;价格&#xff0c;销量&#…