Tangram系列(二) iOS Tangram 通過(guò)數(shù)據(jù)生成動(dòng)態(tài)頁(yè)面詳解

在前面介紹了Tangram框架的歷史由來(lái)和基本概念后,說(shuō)明了Tangram解決了什么問(wèn)題,可以用來(lái)做什么,核心是按照業(yè)務(wù)組件化粒度來(lái)實(shí)現(xiàn)動(dòng)態(tài)流式頁(yè)面。在此基礎(chǔ)上本文著重分析iOS上Tangram框架如何使用json數(shù)據(jù)來(lái)動(dòng)態(tài)生成流式頁(yè)面。

Tangram如何用json描述頁(yè)面

??首先要通過(guò)json數(shù)據(jù)生成視圖,我們得明白用怎么樣的格式來(lái)描述一個(gè)頁(yè)面。
??無(wú)論是iOS或是Android UI是跟用戶直接交互的重要部分,為了描述一個(gè)頁(yè)面iOS和Android都有各自的一套解決方案和實(shí)現(xiàn)思路。平常native開發(fā)的更多的是一個(gè)2D的界面,為了描述這個(gè)界面,iOS和Android都抽象了一個(gè)View的概念,一個(gè)界面是由多個(gè)View組成的,View是頁(yè)面的最小顯示單位,而整個(gè)界面是從一個(gè)根View節(jié)點(diǎn)出發(fā)的,也就是一個(gè)頁(yè)面就是一棵View組成的樹。
??最后這棵View樹如何顯示到屏幕上,這涉及到如何在平面坐標(biāo)系上放置每個(gè)View,合成位圖傳到GPU,GPU上傳到幀緩存,最后顯示到屏幕上。
??iOS上是View都有一個(gè)Frame,平面坐標(biāo)系的x坐標(biāo)、y坐標(biāo)、寬和高,既每個(gè)View知道自己在父View的位置和寬高,而屏幕左上角為(0,0)坐標(biāo)。這樣最后通過(guò)計(jì)算可以知道每個(gè)View在屏幕的位置和大小,其中還有一個(gè)z坐標(biāo)的概念,產(chǎn)生重疊知道哪個(gè)View在上,哪個(gè)在下。iOS上面是根據(jù)View的層級(jí),默認(rèn)從下往上的。隨著iOS設(shè)備屏幕類型的增多,蘋果也引入了AutoLayout,通過(guò)添加視圖之間的關(guān)系約束,最后確定View的位置。


15756188328638.jpg

??Android上面因?yàn)槠聊凰槠瘑?wèn)題,使用的是layout+View的方式來(lái)布局,抽象出一個(gè)布局容器的類,通過(guò)布局容器類型,綜合屏幕寬高、分辨率和View的約束最終確定每個(gè)View的位置。這樣在不同屏幕上能有一致的顯示效果。
??Tangram要保證一套Json格式在多端的同一性,如果采用iOS的布局,Json會(huì)非常復(fù)雜,而且在Android上沒辦法適配,因此最后選擇借鑒Android上的布局方案,使用布局+組件的形式來(lái)描述頁(yè)面。
??最后頁(yè)面描述如下圖:


15756232811833.jpg

??最后頁(yè)面由布局和組件組成的樹形結(jié)構(gòu)組成,組件其實(shí)就是一個(gè)業(yè)務(wù)組成的View,通過(guò)type映射成native的業(yè)務(wù)視圖。
??其中組件又由三部分組成,樣式、業(yè)務(wù)數(shù)據(jù)和交互,布局也有樣式。首先根據(jù)樣式,參照Anroid抽象出style通用格式,包含margin、padding、width、height等,并支持?jǐn)U展。Element的業(yè)務(wù)數(shù)據(jù)完全跟業(yè)務(wù)相關(guān),由native和業(yè)務(wù)方約定,事件則抽離出來(lái)了EventBus。
??Tangram參照Android的布局,使用Layout+Element+Event靈活一個(gè)頁(yè)面,其中Layout、Element和Event通過(guò)type和端上做一一映射。

{
                "type": "container-threeColumn",
                "id": "173",
                "style": {
                    "margin": [
                        "20",
                        "30",
                        "20",
                        "30"
                    ]
                },
                "items": [
                    {
                        "type": "TmallComponent2",
                        "imgUrl": "https://gw.alicdn.com/tps/TB1Nin9JFXXXXbXaXXXXXXXXXXX-224-224.png",
                        "title": "榜單"
                    },
                    {
                        "type": "TmallComponent2",
                        "imgUrl": "https://gw.alicdn.com/tps/TB1Nin9JFXXXXbXaXXXXXXXXXXX-224-224.png",
                        "title": "最新"
                    },
                    {
                        "type": "TmallComponent2",
                        "imgUrl": "https://gw.alicdn.com/tps/TB1Nin9JFXXXXbXaXXXXXXXXXXX-224-224.png",
                        "title": "歌手"
                    }
                ]
            }

Tangram整體框架和各模塊功能

??明白Tangram的json格式規(guī)范后,接下來(lái)就是native如何解析數(shù)據(jù)和生成視圖了,在此之前,我們應(yīng)該先從整體上把握這個(gè)框架的結(jié)構(gòu)。最好的方式是先從模塊劃分、數(shù)據(jù)處理時(shí)序圖、架構(gòu)類圖上面分析,避免一開始就深入某一個(gè)細(xì)節(jié)。

??框架目錄如下:


15756253469944.jpg
  • Core:TangramView視圖,自定義的類似TableView的視圖,最外層容器
  • EventBus:事件處理模塊
  • Factory:布局工廠、數(shù)據(jù)模型工廠、組件工廠,通過(guò)注冊(cè)機(jī)制來(lái)創(chuàng)建對(duì)應(yīng)類型的布局、模型和組件
  • Helper:數(shù)據(jù)解析管理器和生成管理器,用來(lái)管理工廠和解析
  • Model:通用組件數(shù)據(jù)模型
  • Protocols:面向抽象接口編程,定義了工廠需要遵循的接口,布局、組件、數(shù)據(jù)模型需要遵循的協(xié)議,全部使用接口來(lái)定義,非常靈活

??解析生成框架類圖:

15756261943795.jpg

??其中TangramDefaultDataSourceHelper類用來(lái)封裝TangramDefaultLayoutFactory、TangramDefaultItemModelFactory、TangramDefaultElementFactory三個(gè)工廠,提供數(shù)據(jù)解析成Layout、ItemModel、Element,而這四個(gè)類遵循設(shè)計(jì)模式的開閉原則,都是用注冊(cè)的方式,方便外接擴(kuò)展,但是不建議修改。
??TangramLayoutParseHelper類是專門用來(lái)解析layout數(shù)據(jù)的,這個(gè)類沒有使用注冊(cè)的方式來(lái)解耦合,是因?yàn)椴煌膌ayout之前有很多相似的邏輯,而且layout數(shù)據(jù)格式比較統(tǒng)一。
??TangramView類圖:
15756262359265.jpg

Tangram如何解析生成Layout和Element

??通過(guò)上面的類圖和機(jī)構(gòu)圖,說(shuō)明了Tangram解析和生成這塊用到的類,其中定義了很多接口,面向接口編程,同時(shí)使用工廠設(shè)計(jì)模式對(duì)修改關(guān)閉對(duì)擴(kuò)展開放。
??數(shù)據(jù)處理流程圖:


15756296561400.jpg

執(zhí)行詳細(xì)流程圖:


15756301700794.jpg
  1. 將json數(shù)據(jù)轉(zhuǎn)為iOS系統(tǒng)的ArrayDictionary,使用TangramDefaultDataSourceHelper對(duì)數(shù)據(jù)進(jìn)行解析
  2. TangramDefaultDataSourceHelper中調(diào)用注冊(cè)的TangramDefaultLayoutFactory根據(jù)不同的類型將數(shù)據(jù)解析成不同的layout對(duì)象,同時(shí)調(diào)用TangramLayoutParseHelper解析類進(jìn)一步解析數(shù)據(jù),并填充數(shù)據(jù)到layout對(duì)象上
  3. 解析完layout后,調(diào)用注冊(cè)的Item工廠TangramDefaultItemModelFactory解析ItemModel數(shù)據(jù),ItemModel是Element的一個(gè)暫存數(shù)據(jù)對(duì)象
  4. ItemModel是定義的一個(gè)通用組件類,里面包含基礎(chǔ)的屬性,例如margin、height、width等,同時(shí)提供兩個(gè)map來(lái)存儲(chǔ)額外的樣式數(shù)據(jù)和業(yè)務(wù)數(shù)據(jù),以此來(lái)支持?jǐn)U展
  5. TangramView調(diào)用代理方法,通知要顯示相應(yīng)位置的組件時(shí),再次使用TangramDefaultDataSourceHelper,調(diào)用里面注冊(cè)的TangramDefaultElementFactory工廠,根據(jù)ItemModel生成相應(yīng)的組件視圖,并填充相應(yīng)的數(shù)據(jù),同時(shí)將擴(kuò)展的屬性通過(guò)KVC映射到相應(yīng)的組件上。

??通過(guò)上面的一整套流程和框架,最終將json數(shù)據(jù)轉(zhuǎn)換成頁(yè)面顯示到屏幕上。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容