如何打造移動(dòng)端布局動(dòng)態(tài)化

一、前言

《如何打造移動(dòng)端Hybrid框架》一篇中我闡述了四類移動(dòng)端動(dòng)態(tài)化方案。

動(dòng)態(tài)化方案對(duì)比

其中布局動(dòng)態(tài)化是一種應(yīng)對(duì)交互不算復(fù)雜,對(duì)性能要求比較高的實(shí)現(xiàn)方案,接下來我們展開聊一聊這個(gè)話題,下面我將以問答的形式來層層剝開布局動(dòng)態(tài)化的面紗。

二、問與答

問題一:為什么是布局動(dòng)態(tài)化?

答:布局動(dòng)態(tài)化主要應(yīng)用為重展現(xiàn),輕交互的場(chǎng)景,與RN或Flutter相比它給整個(gè)App帶來的負(fù)擔(dān)會(huì)更小,更穩(wěn)定,而且性能也較高,實(shí)現(xiàn)的技術(shù)復(fù)雜度也適中,對(duì)于很多核心場(chǎng)景都適用。

問題二:為什么是Flexbox?

答:Web界的布局標(biāo)桿,可適應(yīng)各種復(fù)雜場(chǎng)景,已在Web界得到了充分的驗(yàn)證。

問題三:為什么是JSON?

答:JSON天生就是結(jié)構(gòu)化的語言,看過RN源碼的同學(xué)肯定知道,JSON和RN是渾然天成的,從實(shí)現(xiàn)的角度會(huì)極大縮減成本。

問題四:如何設(shè)計(jì)和實(shí)現(xiàn)?

答:我們可以把布局動(dòng)態(tài)化拆分為對(duì)外接口層(創(chuàng)建和銷毀邏輯的處理邏輯)、界面描述層(DSL的定義和數(shù)據(jù)綁定的實(shí)現(xiàn))、界面展示層(界面適配的實(shí)現(xiàn)和事件交互的實(shí)現(xiàn))、基礎(chǔ)渲染層(布局管理的實(shí)現(xiàn),渲染管理的實(shí)現(xiàn)和動(dòng)畫管理的實(shí)現(xiàn))。

如何實(shí)現(xiàn)布局動(dòng)態(tài)化

對(duì)外接口層

【1】創(chuàng)建和銷毀的處理邏輯

我們?cè)谝粋€(gè)App里可能會(huì)有多處地方使用到布局動(dòng)態(tài)化,首先我們需要在業(yè)務(wù)入口處增加RootView,并且和一個(gè)ViewManager的實(shí)例進(jìn)行綁定,后續(xù)都由這個(gè)ViewManager實(shí)例來管理RootView的創(chuàng)建和銷毀,從實(shí)踐的角度來看建議一個(gè)ViewManager實(shí)例對(duì)應(yīng)一個(gè)RootView實(shí)例。

界面描述層

【1】DSL的定義

DSL的定義首先要保障雙端統(tǒng)一,一種取巧的方案是將RN的DSL定義遷移過來,但這里有一個(gè)不大不小的坑,就是RN在實(shí)現(xiàn)的時(shí)候,選擇在JS層抹平雙端的差異,這就導(dǎo)致我們需要將遷移過來的JSON定義雙端抹平,我們選擇的是遵照iOS的定義去抹平Android。

【2】數(shù)據(jù)綁定的實(shí)現(xiàn)

在實(shí)現(xiàn)的過程中,我們需要布局模板+業(yè)務(wù)數(shù)據(jù)+解析規(guī)則=布局和渲染的數(shù)據(jù)。

1)布局模板,一個(gè)JSON文件,會(huì)預(yù)置在客戶端內(nèi)并隨包管理平臺(tái)進(jìn)行動(dòng)態(tài)更新,它里邊主要描述了這個(gè)界面的布局以及渲染的樣式。

2)規(guī)則解析,布局模板里的JSON是無法被布局引擎和渲染引擎理解的,因?yàn)楹芏鄬傩缘闹凳且蕾嚇I(yè)務(wù)數(shù)據(jù)傳過來的,這個(gè)時(shí)候需要使用遞歸,按照布局模板屬性值里定義的a.b.c,在業(yè)務(wù)數(shù)據(jù)里按照層次關(guān)系進(jìn)行查找,查找到值后再填充到布局模板的屬性值里,進(jìn)而得到一個(gè)布局引擎和渲染引擎能理解的JSON。

3)業(yè)務(wù)數(shù)據(jù),就是我們平時(shí)業(yè)務(wù)開發(fā)中,服務(wù)器返回的JSON數(shù)據(jù)。

界面展示層

【1】界面適配的實(shí)現(xiàn)

1)長(zhǎng)度,依賴系統(tǒng)原生機(jī)制,Android使用dp,iOS使用pt。

2)字號(hào),依賴系統(tǒng)原生機(jī)制,Android使用sp,iOS使用pt。

3)圖片,依賴系統(tǒng)原生的適配機(jī)制,Android適配mdpi/hdpi/xhdpi,iOS適配1x/2x/3x。

【2】事件交互的實(shí)現(xiàn)

客觀上講,布局動(dòng)態(tài)化在事件交互上的動(dòng)態(tài)性是比較弱的,需要預(yù)先定義好一些事件行文,如單擊,雙擊等,RN的內(nèi)部實(shí)現(xiàn)了大量的事件交互行為,我們可以直接復(fù)用,但需要自己定義行為,比如點(diǎn)擊一個(gè)按鈕要跳轉(zhuǎn)到什么鏈接。

基礎(chǔ)渲染層

【1】布局管理的實(shí)現(xiàn)

上邊提到布局規(guī)范選擇Flexbox,在實(shí)現(xiàn)上雙端我們都選擇了Yoga,各種Flexbox的屬性支持的都比較好。

【2】渲染管理的實(shí)現(xiàn)

布局管理只能計(jì)算出view在界面的位置大小,真正顯示出來要依賴渲染引擎,使用平臺(tái)自身的渲染是最佳的,我們借鑒RN的思想選擇使用系統(tǒng)原生view的渲染方式進(jìn)行渲染。

【3】動(dòng)畫管理的實(shí)現(xiàn)

借鑒RN的思想實(shí)現(xiàn)并支持Frame動(dòng)畫,Spring動(dòng)畫,Decay動(dòng)畫。

三、結(jié)語

布局動(dòng)態(tài)化的實(shí)現(xiàn)已經(jīng)不是什么稀奇的技術(shù),在行業(yè)內(nèi)有比較成熟的做法,在設(shè)計(jì)和實(shí)現(xiàn)的過程中借鑒和參考RN的很多思想和實(shí)現(xiàn),這既可以保障穩(wěn)定性也可以高效快速開發(fā),最后非常感謝Meta工程師們開源出RN這么優(yōu)秀的框架,在過程中有一些代碼思考和大家分享下。

1)RN的一個(gè)NativeView會(huì)和一個(gè)Manager進(jìn)行綁定,在Manager中會(huì)清晰的找到NativeView的各種屬性,包括重命名的屬性,Android使用標(biāo)注的方式,iOS使用宏的方式,個(gè)人覺著這樣的好處是不用使用繁瑣的文檔來記錄一個(gè)NativeView到底都有什么屬性,有改動(dòng)都在代碼里呈現(xiàn),也非常便于查找。

2)RN選擇在JS層抹平雙端JSON描述的差異是可以理解的,Android和iOS本來就是存在差異化的,有JS層必然會(huì)在這一層抹平,但如果能把JSON的描述也保持一致,在Android和iOS端做差異化處理,感覺這樣會(huì)更好一些。

3)RN雙端代碼一致性還是很高的,這一點(diǎn)還是能看出Meta工程師站在更高角度去實(shí)現(xiàn)代碼的功力。

最后編輯于
?著作權(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ù)。

相關(guān)閱讀更多精彩內(nèi)容

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