設(shè)計(jì)稿(UI視圖)自動(dòng)生成代碼方案的探索(ui界面生成)
設(shè)計(jì)稿(UI視圖)轉(zhuǎn)代碼是前端工程師日常不斷重復(fù)的工作,這部分工作復(fù)雜度較低但工作占比較高,所以提升設(shè)計(jì)稿轉(zhuǎn)代碼的效率一直是前端工程師追求的方向之一。
此前,前端工程師嘗試過(guò)將業(yè)務(wù)組件模塊化構(gòu)建成通用視圖庫(kù),并通過(guò)拖拽、拼接等形式搭建業(yè)務(wù)模塊,從而實(shí)現(xiàn)視圖復(fù)用,降低設(shè)計(jì)稿轉(zhuǎn)代碼的研發(fā)成本。但隨著業(yè)務(wù)的發(fā)展和個(gè)性化的驅(qū)動(dòng),通用視圖庫(kù)無(wú)法覆蓋所有應(yīng)用場(chǎng)景,本文提出了一種設(shè)計(jì)稿自動(dòng)生成代碼的方案。
1 背景
設(shè)計(jì)稿(UI視圖)轉(zhuǎn)代碼是前端工程師日常不斷重復(fù)的工作,這部分工作復(fù)雜度較低但工作占比較高,所以提升設(shè)計(jì)稿轉(zhuǎn)代碼的效率一直是前端工程師追求的方向之一。此前,前端工程師嘗試過(guò)將業(yè)務(wù)組件模塊化構(gòu)建成通用視圖庫(kù),并通過(guò)拖拽、拼接等形式搭建業(yè)務(wù)模塊,從而實(shí)現(xiàn)視圖復(fù)用,降低設(shè)計(jì)稿轉(zhuǎn)代碼的研發(fā)成本。但隨著業(yè)務(wù)的發(fā)展和個(gè)性化的驅(qū)動(dòng),通用視圖庫(kù)無(wú)法覆蓋所有應(yīng)用場(chǎng)景,本文提出了一種設(shè)計(jì)稿自動(dòng)生成代碼的方案。
目前,業(yè)內(nèi)主流的代碼生成方案有兩種,一種是通過(guò)訓(xùn)練神經(jīng)網(wǎng)絡(luò),從圖片或草圖直接生成代碼,以微軟Sketch2json為代表;另一種是基于Sketch源文件,從中解析出圖層信息轉(zhuǎn)化成DSL并生成代碼,以imgCook為代表。經(jīng)過(guò)實(shí)踐,我們發(fā)現(xiàn)第一種方案基于神經(jīng)網(wǎng)絡(luò)的代碼生成算法雖然簡(jiǎn)單粗暴,但復(fù)雜層布局的準(zhǔn)確率較低、可解釋程度不高導(dǎo)致后續(xù)無(wú)法持續(xù)優(yōu)化。方案二中Sketch源文件信息量豐富、算法自定義程度高、優(yōu)化空間大。因此,我們調(diào)研了業(yè)界基于Sketch的代碼自動(dòng)生成方案(已對(duì)外公布或者開(kāi)源),發(fā)現(xiàn)了一些不足并嘗試解決,下面從算法準(zhǔn)確率、代碼可讀性、研發(fā)流程覆蓋度等方面做一下對(duì)比(該對(duì)比結(jié)果僅考察業(yè)界方案對(duì)我們自己業(yè)務(wù)的適用性,實(shí)際結(jié)果可能存在差異):
- 算法準(zhǔn)確率方面:淘寶imgCook支持基于A(yíng)I的組件識(shí)別,不支持成組布局,準(zhǔn)確率中等(從官網(wǎng)了解到可以識(shí)別循環(huán)布局,但不能識(shí)別出測(cè)試樣本中的循環(huán)布局),58 Picasso僅支持原始組件的識(shí)別,復(fù)雜組件生成錯(cuò)誤較多,不支持成組/懸浮/循環(huán)布局,準(zhǔn)確率較低。
- 代碼可讀性方面:淘寶imgCook在生成布局時(shí),測(cè)試樣本中圖層重疊區(qū)域使用到了基于根布局的絕對(duì)定位方式,不符合RD預(yù)期,可讀性一般,而我們的方案使用相對(duì)定位方式,可讀性較好。
- 研發(fā)流程覆蓋度方面:淘寶imgCook從RD視角構(gòu)建了一個(gè)IDE,支持在IDE中完成樣式調(diào)整、邏輯綁定;而我們的方案從產(chǎn)研協(xié)作視角出發(fā),支持?jǐn)?shù)據(jù)、邏輯、埋點(diǎn)的可視化配置及上線(xiàn)。
2 方案介紹
如圖所示,配置平臺(tái)主要分成三塊包括:設(shè)計(jì)稿轉(zhuǎn)視圖樹(shù)(UI2DSL)、視圖樹(shù)轉(zhuǎn)代碼(DSL2Code)、以及業(yè)務(wù)信息綁定,下面簡(jiǎn)單介紹一下每一塊的作用。
- 設(shè)計(jì)稿轉(zhuǎn)DSL視圖樹(shù)(UI2DSL):將設(shè)計(jì)稿轉(zhuǎn)化成平臺(tái)無(wú)關(guān)的DSL視圖樹(shù)。
- 視圖樹(shù)轉(zhuǎn)代碼(DSL2Code):將DSL視圖樹(shù)轉(zhuǎn)化成基于Flex布局的MTFlexBox靜態(tài)代碼。
- 業(yè)務(wù)信息綁定:提供可視化配置工具,支持MTFlexBox靜態(tài)代碼綁定后臺(tái)數(shù)據(jù)、業(yè)務(wù)邏輯、以及曝光/點(diǎn)擊等埋點(diǎn)邏輯。
2.1 設(shè)計(jì)稿轉(zhuǎn)視圖樹(shù)(UI2DSL)
UI2DSL主要經(jīng)歷以下四個(gè)步驟:
2.1.1 設(shè)計(jì)稿導(dǎo)入
在日常開(kāi)發(fā)過(guò)程中,我們接觸比較多的組件有按鈕、標(biāo)題、進(jìn)度條、評(píng)分組件等,但是Sketch數(shù)據(jù)源中并沒(méi)有這些組件只有圖層信息,圖層是設(shè)計(jì)師在設(shè)計(jì)UI視圖時(shí)用到的視圖控件。組件與圖層的對(duì)應(yīng)關(guān)系是一對(duì)多的關(guān)系,圖層在Sketch數(shù)據(jù)源中的表現(xiàn)形式如下圖中的JSON數(shù)據(jù)結(jié)構(gòu)所示,描述了圖層的坐標(biāo)、大小等信息,后續(xù)布局生成就是基于對(duì)圖層的切割來(lái)實(shí)現(xiàn)的。
[ { "class_name":"MSTextLayer", "font_face":"PingFangSC-Medium", "font_size":13.44, "height":36.5, "index":8, "line_height":18.24, "name":"恒都民生精選豬小排帶骨400g±25g", "object_id":"EF55F482-A690-4EC2-8A6E-6E7D2C6A9D91", "opacity":0.9000000357627869, "text":"恒都民生精選豬小排帶骨400g±25g", "text_align":"left", "text_color":"#FF000000", "type":"text", "width":171.8, "x":164.2, "y":726.7 }, //......]
2.1.2 組件識(shí)別
從上面的數(shù)據(jù)源可以看出,圖層有圖片、文字、矩形等基本類(lèi)型,在組件識(shí)別這一步圖層需要被轉(zhuǎn)化成文字/圖片/進(jìn)度條/評(píng)分組件/價(jià)格組件/角標(biāo)等日常開(kāi)發(fā)使用的組件類(lèi)型。但是目前我們的進(jìn)展還停留在只能將圖層識(shí)別為文字或者圖片的階段,后續(xù)我們將接入淘寶開(kāi)源的pipcook框架,基于神經(jīng)網(wǎng)絡(luò)算法進(jìn)行更加豐富的組件類(lèi)型識(shí)別。
2.1.3 可視化干預(yù)
設(shè)計(jì)稿作為輸入源是設(shè)計(jì)稿自動(dòng)轉(zhuǎn)代碼的基礎(chǔ),這對(duì)設(shè)計(jì)稿的設(shè)計(jì)規(guī)范要求較高。但在實(shí)踐中,我們發(fā)現(xiàn)設(shè)計(jì)師會(huì)利用Sketch中的基本圖形(每個(gè)圖形最終形成數(shù)據(jù)源中的一個(gè)圖層)疊加來(lái)描述一個(gè)組件的視覺(jué)效果,因此設(shè)計(jì)稿中不可避免會(huì)出現(xiàn)冗余圖層的問(wèn)題,干擾DSL的生成。雖然我們也嘗試了利用自動(dòng)化的手段刪除冗余圖層,但對(duì)于算法不能識(shí)別的部分(例如:圖片上有一個(gè)文本圖層,但是實(shí)際情況中文本是顯示在圖片里的,這個(gè)時(shí)候無(wú)法從算法層面決定是否刪除文本),仍然需要靠人工進(jìn)行圖層刪除、合并等,否則無(wú)法正常生成DSL。設(shè)計(jì)稿主要有以下幾類(lèi)問(wèn)題。
圖層未合并
上圖是從設(shè)計(jì)稿解析出來(lái)的結(jié)果,可以發(fā)現(xiàn)在“美團(tuán)優(yōu)選”文字上方的圖片中有很多紅色的矩形框(每個(gè)矩形框是一個(gè)單獨(dú)的圖層),而算法預(yù)期的輸入是一個(gè)圖層,因此需要在算法處理前將多個(gè)圖層合并成一個(gè)圖層,右側(cè)的三張圖也有類(lèi)似問(wèn)題。我們與設(shè)計(jì)同學(xué)進(jìn)行過(guò)溝通,設(shè)計(jì)同學(xué)表示愿意在產(chǎn)出設(shè)計(jì)稿之前將圖層進(jìn)行合并,但由于目前無(wú)法提供檢測(cè)機(jī)制(圖層合并是否有遺漏無(wú)法自動(dòng)檢測(cè)出來(lái)),也就無(wú)法徹底避免圖層未合并的問(wèn)題。
圖層位置交叉
實(shí)踐中發(fā)現(xiàn)當(dāng)設(shè)計(jì)稿中不同字體/大小/顏色的文字排列在一起時(shí),解析出來(lái)的圖層信息往往會(huì)出現(xiàn)重疊的情況,由于DSL視圖樹(shù)算法依賴(lài)位置來(lái)確定不同組件的約束關(guān)系,因此位置的交叉會(huì)對(duì)算法準(zhǔn)確度造成較大的影響。
復(fù)雜背景圖層
上圖中紅色背景是由2個(gè)圖層(2個(gè)藍(lán)色矩形框)拼接形成的,左圖上的藍(lán)色圖層是純色,右圖上的藍(lán)色圖層是漸變色,在兩個(gè)圖層未合并的情況下,算法生成的代碼將會(huì)出錯(cuò)。
上面提出的問(wèn)題,通過(guò)約束設(shè)計(jì)師來(lái)達(dá)到設(shè)計(jì)稿的規(guī)范化,難度較大,所以我們提供了可視化干預(yù)工具。下面對(duì)上述問(wèn)題做一個(gè)簡(jiǎn)單的總結(jié):
- 問(wèn)題一:圖層未合并問(wèn)題肉眼很容易識(shí)別出來(lái),利用工具將冗余圖層進(jìn)行快速合并刪除即可。
- 問(wèn)題二:圖層交叉問(wèn)題肉眼不易識(shí)別,因此我們提供了檢測(cè)工具,基于檢測(cè)工具可以對(duì)設(shè)計(jì)稿中的交叉問(wèn)題快速修復(fù)。
- 問(wèn)題三:復(fù)雜背景問(wèn)題肉眼不易識(shí)別,暫時(shí)也沒(méi)有有效的檢測(cè)工具,用戶(hù)可以采用邊干預(yù)邊生成的方式生成DSL。
可視化干預(yù)是UI2DSL重要的一環(huán),經(jīng)過(guò)可視化干預(yù),將不標(biāo)準(zhǔn)的設(shè)計(jì)稿轉(zhuǎn)化為標(biāo)準(zhǔn)的圖層信息后再輸入給算法,可以極大地提升算法的準(zhǔn)確率。 這里我們和imgCook的處理方式有一個(gè)區(qū)別:imgCook在引入了閾值處理等算法后(更智能,出錯(cuò)概率更大),可視化干預(yù)能力主要體現(xiàn)在事后,而我們?cè)谏蒁SL之前允許用戶(hù)對(duì)圖層進(jìn)行干預(yù),在干預(yù)時(shí)用戶(hù)面對(duì)的是直觀(guān)的圖層信息,可以有效降低工具的使用門(mén)檻(更穩(wěn)定,效果更好)。
2.1.4 視圖樹(shù)生成
將扁平的數(shù)據(jù)源轉(zhuǎn)化為樹(shù)狀結(jié)構(gòu)的DSL,這個(gè)過(guò)程如果是人腦來(lái)做會(huì)怎么思考呢?先確定布局的整體結(jié)構(gòu)是行布局或者列布局,然后再確定局部區(qū)域應(yīng)該是什么布局結(jié)構(gòu),最后組裝起來(lái)形成視圖樹(shù)。這個(gè)過(guò)程與遞歸算法類(lèi)似,因此我們采用了遞歸算法作為算法的主框架,同時(shí)引入了“橫豎切割 布局結(jié)構(gòu) 模型評(píng)估”三大利器。
利器一:橫豎切割
生成DSL時(shí)采用了整分的思路,即將大布局不斷的切分成小布局,下面以動(dòng)畫(huà)的形式看一下簡(jiǎn)化過(guò)的DSL生成過(guò)程:
將設(shè)計(jì)稿一部分區(qū)域視為一個(gè)子區(qū)域,最開(kāi)始的時(shí)候子區(qū)域和整個(gè)模板的面積一樣大,基于圖層的位置、大小信息,計(jì)算每個(gè)圖層的上/下/左/右邊緣坐標(biāo)與其他圖層的相對(duì)關(guān)系,就可以尋找到切割點(diǎn)(如上圖中紅色箭頭所指的位置)。接下來(lái)依據(jù)切割點(diǎn),將子區(qū)域切割成更小的子區(qū)域,在切割的過(guò)程中如果切割點(diǎn)是橫向的,則生成列布局;如果切割點(diǎn)是縱向的,則生成行布局。通過(guò)不斷的切割子區(qū)域得到更小的子區(qū)域,直到所有的子區(qū)域只剩下圖片或者文本等不可切割的圖層,這樣就可以生成完整的DSL視圖樹(shù)了。為了方便讀者理解,圖例中只演示了行布局、列布局的切分過(guò)程,實(shí)際情況還包含了其他布局類(lèi)型,會(huì)要復(fù)雜許多。
這里還要注意一個(gè)問(wèn)題,當(dāng)有3個(gè)切割點(diǎn)時(shí),我們選擇了直接將子區(qū)域切割成4個(gè)子區(qū)域,實(shí)際上我們可以只選擇1個(gè)切割點(diǎn)進(jìn)行切割,也可以選擇2個(gè)切割點(diǎn)進(jìn)行切割,當(dāng)有N個(gè)切割點(diǎn)時(shí),實(shí)際上存在(N的階乘 1)種切割方式,具體選擇哪種切割方式,我們會(huì)在利器三中討論。
利器二:布局結(jié)構(gòu)
每個(gè)圖層都是一個(gè)矩形,為了生成布局結(jié)構(gòu)只能依賴(lài)矩形的上下左右坐標(biāo)信息。因此,對(duì)布局結(jié)構(gòu)進(jìn)行分類(lèi)時(shí),我們根據(jù)矩形與矩形之間的位置關(guān)系(相交、相離和包含關(guān)系)做了以下分類(lèi)。
注意:從生成DSL的結(jié)果來(lái)看,包含布局和成組布局的處理方式其實(shí)是一樣的,都是使用類(lèi)似于FrameLayout的層疊布局包含內(nèi)部圖層元素,但是我們?nèi)匀槐3址诸?lèi)原則(矩形之間的位置關(guān)系)不變。
上圖中,相離、包含比較好理解,為什么兩個(gè)圖層相交的時(shí)候,會(huì)有成組和懸浮兩種類(lèi)型的布局結(jié)構(gòu)呢?我們看下上述成組布局、懸浮布局兩個(gè)設(shè)計(jì)稿中分別標(biāo)出了相交的元素A、B,它們?cè)谖恢蒙系南鄬?duì)關(guān)系是一樣的,都是A、B兩個(gè)圖層對(duì)應(yīng)的矩形框發(fā)生了交叉。但是我們希望理想態(tài)的DSL視圖樹(shù)卻有所差異,如下圖所示:
- 成組布局中:A、B邏輯上是一個(gè)整體,交叉是必然的,最終DSL中A、B被層疊布局包含,層疊布局中沒(méi)有其他元素。
- 懸浮布局中:A、B邏輯上不是整體,只是碰巧交叉了,最終DSL中A、B分別在不同的層級(jí)中。
因此,對(duì)于圖層相交時(shí)可能有兩種類(lèi)型的布局結(jié)構(gòu),分別是成組布局和懸浮布局。從上圖可以看出使用成組布局還是懸浮布局是由圖層內(nèi)容決定的,那么就需要算法理解圖層內(nèi)容了,比如基于A(yíng)I構(gòu)建樣本庫(kù),記住所有的角標(biāo)樣式(上面表格中4描述的),下次遇到角標(biāo)相交時(shí)就生成成組布局??紤]到AI模型也是對(duì)規(guī)則的抽象,我們先搭建一套自定義識(shí)別規(guī)則。成組布局其位置信息是有規(guī)律可循的,例如:角標(biāo)經(jīng)常出現(xiàn)在右上角,標(biāo)簽經(jīng)常出現(xiàn)在左上角,頭像經(jīng)常橫向或者縱向交叉等,因此我們針對(duì)圖層之間的位置關(guān)系構(gòu)建了交叉模型,如下圖所示:
上圖的交叉模型可以記住歷史模板中成組布局圖層之間的位置關(guān)系,下次遇到相交布局時(shí)判斷是否在歷史規(guī)則庫(kù)中即可完成識(shí)別,如果在就按成組布局處理否則按照懸浮布局處理。下圖是通過(guò)歷史模板構(gòu)建的成組規(guī)則庫(kù)。
上面介紹了本方案中涉及的5種布局類(lèi)型,目前來(lái)看這五種布局類(lèi)型可以描述所有的模板布局,并且生成代碼符合RD的預(yù)期。下面展示兩個(gè)設(shè)計(jì)稿DSL實(shí)例:
利器三:模型評(píng)估
在介紹橫豎切割時(shí),可以看到當(dāng)存在多個(gè)切割點(diǎn)時(shí),對(duì)所有切割點(diǎn)同時(shí)進(jìn)行了切割,但實(shí)際上算法在切割時(shí)復(fù)雜度會(huì)更高,當(dāng)有三個(gè)切割點(diǎn)時(shí),實(shí)際上有5種切割方式,每種切割方式都會(huì)生成一個(gè)DSL。既然有5種切割方式,那么到底應(yīng)該選擇哪一種DSL呢?模型評(píng)估算法就是用來(lái)解決這個(gè)問(wèn)題的。
目前模型評(píng)估算法有兩個(gè)指標(biāo):布局節(jié)點(diǎn)數(shù)和逆布局指數(shù)。
- DSL中布局節(jié)點(diǎn)數(shù)越少,切割方式越好。
- 逆布局指數(shù)用來(lái)評(píng)估DSL中的行列布局的合理程度,其中逆布局指數(shù)越大越不合理,反之,逆布局指數(shù)越小,切割方式越好。
以下圖為例,看下視圖不同切割方式下對(duì)應(yīng)的模型評(píng)估方式:
如果模型評(píng)估算法只衡量布局節(jié)點(diǎn)數(shù)的話(huà),那么會(huì)選擇第一種切割方式生成的DSL作為最終的結(jié)果。但實(shí)際上,第二種切割方式更加合理。在切割方式一中,廣告、立即預(yù)約處于一個(gè)列布局中,但是橫向?qū)R方式(交叉軸)卻不一樣,“廣告”是右對(duì)齊,“立即預(yù)約”是左對(duì)齊,逆布局指數(shù)表示交叉軸對(duì)齊方式不一致的節(jié)點(diǎn)數(shù)量,因此通過(guò)逆布局指數(shù),我們可以規(guī)避掉不合理的切割方式。
2.1.5 列表布局
上一節(jié)介紹了基本的布局結(jié)構(gòu),雖然說(shuō)這些布局結(jié)構(gòu)已經(jīng)可以描述所有的UI布局,但是與RD的編碼習(xí)慣還是有一些差異。
對(duì)于上面的布局,RD通常不會(huì)把相同的item寫(xiě)五遍,而是會(huì)將item放在一個(gè)類(lèi)似于ListView的列表組件中,使代碼看起來(lái)簡(jiǎn)潔易懂。因此在DSL生成階段,除了識(shí)別基本的行/列/包含/成組/懸浮布局外,還需要進(jìn)一步識(shí)別行/列布局中的元素是否形成列表布局。在試驗(yàn)過(guò)程中,我們發(fā)現(xiàn)列表布局分為兩種:單狀態(tài)列表組件和多狀態(tài)列表組件。上圖中每一個(gè)item的布局結(jié)構(gòu)都是一樣的,我們稱(chēng)為單狀態(tài)列表組件,再來(lái)看一下多狀態(tài)列表組件(如下圖所示),每個(gè)item有多種狀態(tài)(選中態(tài)和非選中態(tài)),并且不同狀態(tài)的布局結(jié)構(gòu)不一致。
對(duì)行/列布局中單狀態(tài)列表組件的識(shí)別,只需要比較item子視圖樹(shù)的結(jié)構(gòu),子視圖樹(shù)結(jié)構(gòu)一致則判斷為單狀態(tài)列表組件。對(duì)多狀態(tài)列表組件的識(shí)別我們采取了自動(dòng)識(shí)別 人工干預(yù)的方式,自動(dòng)識(shí)別的方式比較粗暴,只要行列布局中子item的寬/高接近,并且子item不是基本組件(基本組件容易形成誤判),就判定為多狀態(tài)列表組件。具體算法是計(jì)算子item寬高的標(biāo)準(zhǔn)差,小于閾值就判定為多狀態(tài)列表組件,否則不是。公式如下:
那為什么還要人工干預(yù)呢?因?yàn)槭欠袷褂昧斜斫M件其實(shí)與產(chǎn)品邏輯相關(guān),但是目前我們無(wú)法將產(chǎn)品文檔中的邏輯識(shí)別出來(lái),只能盡可能識(shí)別出所有的多狀態(tài)列表組件,并允許用戶(hù)對(duì)生成結(jié)果進(jìn)行變更。比如上述送戀人的設(shè)計(jì)稿,產(chǎn)品可能約定每一個(gè)item都有選中態(tài)/非選中態(tài)兩種狀態(tài),也可能是從業(yè)務(wù)角度考慮需要著重突出送戀人這個(gè)item,這時(shí)每個(gè)item就只有一種確定的狀態(tài),這兩種不同的產(chǎn)品邏輯在編寫(xiě)代碼時(shí)有不同的最優(yōu)技術(shù)方案。
2.2 視圖樹(shù)轉(zhuǎn)代碼(DSL2Code)
DSL視圖樹(shù)只是生成代碼的中間產(chǎn)物,還需要對(duì)DSL進(jìn)行代碼還原,DSL2Code主要包括兩個(gè)步驟:屬性推斷、屬性信息調(diào)整。
2.2.1 屬性推斷
屬性推斷包括兩個(gè)部分:樣式屬性和結(jié)構(gòu)屬性。樣式屬性包括字體、背景色、圓角等可以直接通過(guò)數(shù)據(jù)源信息中獲取得到的屬性;結(jié)構(gòu)屬性包括大小、內(nèi)外邊距、主輔軸對(duì)齊等結(jié)構(gòu)信息,這些信息無(wú)法從數(shù)據(jù)源中直接獲取,所以結(jié)構(gòu)信息的推斷是這部分工作的重點(diǎn)。
結(jié)構(gòu)信息推斷算法同樣使用遞歸算法作為主框架,通過(guò)一次遞歸對(duì)所有元素進(jìn)行兩次遍歷來(lái)完成結(jié)構(gòu)信息的推斷。如下圖所示,在對(duì)DSL所有節(jié)點(diǎn)進(jìn)行遞歸遍歷時(shí),把所有元素依次加入隊(duì)列中,遞歸完成后,再把所有節(jié)點(diǎn)依次移出隊(duì)列,這樣一進(jìn)一出便對(duì)所有元素完成了兩次遍歷,我們把這兩次遍歷稱(chēng)為進(jìn)隊(duì)遍歷和出隊(duì)遍歷。
進(jìn)隊(duì)遍歷時(shí),推斷算法根據(jù)數(shù)據(jù)源中信息記錄每個(gè)節(jié)點(diǎn)的大小和位置信息,并根據(jù)位置關(guān)系計(jì)算每個(gè)子節(jié)點(diǎn)在父節(jié)點(diǎn)中期望的主輔軸對(duì)齊方式和內(nèi)外邊距。出隊(duì)遍歷時(shí),父節(jié)點(diǎn)會(huì)根據(jù)子節(jié)點(diǎn)期望的對(duì)齊方式確定父節(jié)點(diǎn)最終的主輔軸對(duì)齊方式,并根據(jù)子節(jié)點(diǎn)的拉伸意圖修正父節(jié)點(diǎn)的大小。拉伸意圖即節(jié)點(diǎn)的大小不固定,根據(jù)顯示內(nèi)容不同,在水平或垂直方向上可能會(huì)變大或變小,例如文本節(jié)點(diǎn)根據(jù)顯示字?jǐn)?shù)的多少長(zhǎng)度會(huì)發(fā)生變化,字?jǐn)?shù)過(guò)多時(shí)甚至還會(huì)換行。
2.2.2 屬性信息調(diào)整
由于輸入源是基于設(shè)計(jì)稿呈現(xiàn)的靜態(tài)效果圖,設(shè)計(jì)稿中每個(gè)元素缺失了真實(shí)的業(yè)務(wù)含義,同樣的展示效果在不同的業(yè)務(wù)場(chǎng)景中會(huì)有不同的屬性要求,對(duì)于這部分內(nèi)容,我們無(wú)法從輸入源中進(jìn)行準(zhǔn)確推斷。為此,我們提供了可視化的屬性信息調(diào)整功能來(lái)輔助代碼生成,頁(yè)面效果如下圖所示,在這個(gè)頁(yè)面可以對(duì)DSL中的所有節(jié)點(diǎn)屬性進(jìn)行查看和修改調(diào)整。
經(jīng)過(guò)業(yè)務(wù)信息補(bǔ)充后,便可進(jìn)行最后的自動(dòng)代碼轉(zhuǎn)化,通過(guò)語(yǔ)法映射自動(dòng)把DSL轉(zhuǎn)化成MTFlexbox模板代碼。
3 成果展示
下面是設(shè)計(jì)稿直接生成代碼未經(jīng)修改展示后的手機(jī)屏幕截圖,可以看到取得了不錯(cuò)的還原效果:
以上就是我們近期對(duì)代碼自動(dòng)生成的探索及實(shí)踐,后續(xù)我們將引入機(jī)器學(xué)習(xí)及神經(jīng)網(wǎng)絡(luò)算法,對(duì)過(guò)程進(jìn)行進(jìn)一步優(yōu)化。如果您有其他的看法或建議,也歡迎在文末進(jìn)行評(píng)論,或者跟我們聯(lián)系。
作者簡(jiǎn)介
田貝、少寬、騰飛等,美團(tuán)平臺(tái)終端業(yè)務(wù)研發(fā)團(tuán)隊(duì)研發(fā)工程師。
團(tuán)隊(duì)簡(jiǎn)介
美團(tuán)平臺(tái)終端業(yè)務(wù)研發(fā)團(tuán)隊(duì)的職責(zé)是保障平臺(tái)業(yè)務(wù)高效、穩(wěn)定迭代的同時(shí),持續(xù)優(yōu)化用戶(hù)體驗(yàn)和研發(fā)效率。團(tuán)隊(duì)負(fù)責(zé)的業(yè)務(wù)主要包括美團(tuán)首頁(yè)等千萬(wàn)級(jí)DAU高頻業(yè)務(wù)以及分享、賬號(hào)、音/視頻等基礎(chǔ)業(yè)務(wù),支撐和對(duì)接外賣(mài)、酒店等30多個(gè)業(yè)務(wù)方。團(tuán)隊(duì)通過(guò)動(dòng)態(tài)化能力建設(shè),加快業(yè)務(wù)上線(xiàn)速度,幫助產(chǎn)品(PM)快速驗(yàn)證業(yè)務(wù)選型,做出業(yè)務(wù)決策;架構(gòu)/服務(wù)標(biāo)準(zhǔn)化體系建設(shè),提升前后端以及平臺(tái)與業(yè)務(wù)線(xiàn)的溝通、合作效率;業(yè)務(wù)監(jiān)控和體驗(yàn)優(yōu)化,有效保障核心業(yè)務(wù)服務(wù)成功率的同時(shí),提升用戶(hù)使用美團(tuán)App過(guò)程中的穩(wěn)定性和流暢性。團(tuán)隊(duì)開(kāi)發(fā)技術(shù)棧包括Android、iOS、React Native、Flexbox等。
招聘信息
美團(tuán)平臺(tái)終端業(yè)務(wù)研發(fā)團(tuán)隊(duì)是一個(gè)活力四射、對(duì)技術(shù)充滿(mǎn)激情的團(tuán)隊(duì),現(xiàn)誠(chéng)聘Android、iOS、FE工程師,歡迎有興趣的同學(xué)投簡(jiǎn)歷至tech@meituan.com(備注:美團(tuán)平臺(tái)終端業(yè)務(wù)研發(fā)團(tuán)隊(duì))。
—
本文系美團(tuán)技術(shù)團(tuán)隊(duì)出品,著作權(quán)歸屬美團(tuán)。歡迎出于分享和交流等非商業(yè)目的轉(zhuǎn)載或使用本文內(nèi)容,敬請(qǐng)注明“內(nèi)容轉(zhuǎn)載自美團(tuán)技術(shù)團(tuán)隊(duì)”。本文未經(jīng)許可,不得進(jìn)行商業(yè)性轉(zhuǎn)載或者使用。任何商用行為,請(qǐng)發(fā)送郵件至tech@meituan.com申請(qǐng)授權(quán)。