0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內(nèi)不再提示

鴻蒙跨端實踐-布局方案介紹

京東云 ? 來源:京東科技 劉寧 ? 作者:京東科技 劉寧 ? 2024-09-18 10:26 ? 次閱讀

作者:京東科技 劉寧

一、前言

動態(tài)化使用 jue 語言(開發(fā)風格與 Vue 一致)開發(fā),對于視圖的布局采用了標準的Flex 布局方式。對于列表類視圖,動態(tài)化提供了、、、等標簽,將子視圖的布局管理封裝到標簽中實現(xiàn),業(yè)務只需要針對標簽簡單地設置相關屬性,即可實現(xiàn)列表類布局,大幅提升研發(fā)效率。同時動態(tài)化也支持絕對布局以及控制視圖的顯示和隱藏等功能,使之能勝任絕大多數(shù)業(yè)務布局場景。

在京東金融App使用動態(tài)化方案適配鴻蒙系統(tǒng)的過程中發(fā)現(xiàn),鴻蒙提供的Flex布局和W3C標準的Flex布局,在一些常用的默認屬性上表現(xiàn)不一致。導致原本在AndroidiOS和web端顯示正確的UI布局在鴻蒙端顯示錯亂。經(jīng)與鴻蒙的工程師溝通,華為出于多方面的考慮,并沒有調(diào)整的計劃。故而決定廢棄鴻蒙提供的布局方式,使用標準的 Flex 布局,引入yoga布局庫(由 FaceBook 提供一個開源的跨平臺的布局引擎),yoga庫的功能是解析視圖的 CSS 設置,獲取視圖的位置(x,y)和尺寸(width,height),直接設置給視圖,確保視圖的正確顯示。

下面詳細介紹一下鴻蒙業(yè)務在實際開發(fā)中高頻使用的布局方式,這些布局方式可以涵蓋95%以上的業(yè)務布局場景。

二、Flex布局

在動態(tài)化上,視圖默認使用的就是flex布局方式(相當于默認設置了 display:flex;)。

1. 概念

容器(container):是指開啟了flex布局的視圖

項目(item):是指容器的子視圖

容器(container)有幾個重要的概念

主軸:item在container上的排列方向,主軸開始的位置叫 main start, 主軸結束的位置叫 main end;item在主軸上占據(jù)的尺寸叫 main size

交叉軸:與主軸垂直的方向;交叉軸開始的位置叫 cross start ,交叉軸結束的位置叫 cross end;item 在交叉軸上占據(jù)的尺寸叫 cross size

2. 容器(container)的常用屬性

2.1 flex-direction

設置主軸方向,默認值是column(以下所說的默認都是指在動態(tài)化上的默認設置)。大部分設置看效果圖已經(jīng)很清晰,故不做過多解釋。

flex-direction: row | row-reverse | column | column-reverse;

不同主軸的顯示效果:

wKgaombqOi6AelE2AAIjZhQBs6c588.png

以下是假設主軸是row的情況下,介紹其他屬性

2.2 flex-wrap

items在主軸上一行顯示不下的情況下的折行方式,默認值是nowrap。

flex-wrap: nowrap | wrap | wrap-reverse;

不同 flex-wrap 的顯示效果:

wKgZombqOi-AL29bAAGwUUF6gOs160.png

2.3 flex-flow

這是flex-direction和flex-wrap的簡寫方式,默認值是 column nowrap 。

flex-flow:column nowrap;

2.4 justify-content

定義item在主軸上的對齊方式,默認值是 flex-start 。

justify-content: flex-start | center | space-between | space-around | space-evenly | flex-end;

不同 justify-content 的顯示效果:

wKgaombqOjCAHfLvAAKuqOhlkpE232.png

2.5 align-items

定義item在交叉軸上的對齊方式,默認是stretch。

align-items: flex-start |  center | flex-end  | stretch;

不同 align-items 的顯示效果:

wKgZombqOjaABkGOAAH7-PDwyk8662.png

2.6 align-content

定義多根主軸在在交叉軸上的對齊方式(單條主軸情況下這個屬性不生效)。

align-content: flex-start | flex-end | center | space-between | space-around | stretch;

這個剛接觸的同學不好理解,什么是主軸的對齊方法?拿 stretch 舉個例子


1 2 3 4 5 6 7

UI顯示效果如下:

wKgaombqOjeABAiYAAC4SFQEcBA569.png

藍色為 container,主軸為 row(flex-direction: row;),支持折行(flex-wrap: wrap;),多行主軸的對齊方式為 stretch(align-content: stretch;),此例中有兩條主軸,因此兩條主軸的高將充滿 container 的高;

第一條主軸中包含視圖 1,2,3,4,5。第二條主軸包含視圖 6,7。單條主軸的在豎直方向上的對齊方式為從上到下(align-items: flex-start;),而 1 改變了所在主軸的交叉軸方向的對齊方式為從下到上(align-self: flex-end),因此1底部對齊,2,3,4,5頂部對齊。 6,7 同理。

3.項目(item)常用屬性

3.1 flex-grow

item在container中的主軸方向上的剩余空間中占據(jù)的分配比例系數(shù)(默認值為0,即不放大)。初次聽起來不理解,看個例子就清楚了:


UI效果如下:

wKgZombqOjeALGRJAABaINQPxRo214.png

由于 item1 寬度為100px,item2 寬度為 50px, container在主軸剩余空間為300-100-50 = 150px;根據(jù)flex-grow 的設置,item1占1/3,為50px;item2占2/3,為100px;故最終 item1 與 item2 平分了主軸空間。

3.2 flex-shrink

item在container中的主軸方向上的縮小系數(shù),默認值為0,即空間不夠,也不縮小。這個屬性僅在container無法承載item的情況下才生效。舉個例子:


由于item1與item2的寬度一致,item1壓縮的比例為item1的2倍,因此最終item1的尺寸是item的2倍。UI效果如下:

wKgaombqOjiAFgMiAABXJlt5GWk225.png

3.3 flex-basis

container在分配多余空間之前,item在主軸方向上占據(jù)的空間,默認值是auto,即本身默認的大小。舉個例子:


由于item1寬度為150px;flex-basis默認為auto,因此默認為150px; item2寬度為150px,但flex-basis為50px,因此在計算所占空間時按50px算,這樣在container的主軸上的剩余空間為 300 - 150 - 50 = 100px;item1和item2的flex-grow都為1,因此,各站剩余空間的1/2。因此item1的寬為150+50=200px;item2為50+50=100px;UI效果如下:

wKgZombqOjmAY7sTAABc0qTvGrE823.png

3.4 flex

這是一個復合屬性,是flex-grow、flex-shrink 、flex-basis的簡寫形式。

flex: none | [    ]

flex:1 等價于 flex: 1 1 auto; flex:none 等價于 flex : 0 0 auto;

注意:在使用的時候經(jīng)常習慣性的使用 flex:1;很多時候大家想要的僅僅是 flex-grow:1;如非必要,盡量不要寫無用約束。

3.4 align-self

item在交叉軸上的布局方式由container的align-items屬性設置,如果某個item想使用別的對齊方式,可以給item設置align-self,就會覆蓋container上的設置。默認值為auto,表示按照container的align-items樣式,如果沒有父元素,則用stretch。

align-self: auto | flex-start | flex-end | center  | stretch;

三、列表類布局

對于列表布局,動態(tài)化提供了、、、、、等標簽,對于多頁面管理提供、等標簽。業(yè)務僅通過修改標簽屬性,即可實現(xiàn)子視圖在列表內(nèi)以不同的布局方式顯示。

以下是列表在京東金融中的幾個具體使用場景。

wKgaombqOjqAPHAwAA8Vls3KnHU491.png

四、絕對布局

對于要脫離視圖文檔流,不受兄弟視圖布局影響,固定顯示于某個指定位置的子視圖,可用絕對布局,比如懸浮圖標等。

1.position: absolute;

.item {
    position: absolute;
    right:10px;
    bottom:20px;
    width:50px;
    height:50px;
 }

絕對定位是相對于父視圖的,使用left、right、top、bottom、width和height來設置。

五、視圖的顯示和隱藏控制

在開發(fā)過沖中,經(jīng)常會用讓視圖顯示或者隱藏的需求。在動態(tài)化上提供如下幾種方式來實現(xiàn),可根據(jù)具體的使用場景選擇使用哪一種。

1. v-if = true | false


這種隱藏方式最徹底,會銷毀視圖,不占據(jù)任何空間,后面如果再需要顯示,則元素會重新創(chuàng)建。這種顯示/隱藏元素比較徹底,會帶來的內(nèi)存的開辟和回收,一般用在只顯示某一種具體元素的場景下使用。

2. display : flex | none;

這種隱藏方式,不會銷毀元素,仍存在于HTML文檔中,仍可通過JavaScript訪問和操作,但元素會從布局上移除,元素不占據(jù)任何空間,不能參與用戶交互事件。

3. v-show=true | false ;

在動態(tài)化上會被解析為display:flex | none;

4. visibility : visible | hidden;

這種隱藏方式,只是從視覺上移除,仍然參與頁面布局,保留元素的位置,無法參與用戶交互。

5. opacity : 0 | 1

這種方式是設置視圖的透明度,在透明度為0時,完全隱藏,視圖仍參與頁面布局,保留元素位置,在 Web、Android 和Harmony端仍可參與用戶交互,但在 iOS 端只有當透明度大于0.1時可以。這個一般用作視圖顯示或者消失的過度動畫。

6. overflow: hidden | visible

規(guī)定視圖超出父視圖邊界時如何處理。在Harmony/iOS/Web 端默認值為visible,即超出可見,Android端默認值為hidden,超出不可見。如果設置了 visible ,如果視圖本身添加了事件,對于超出父視圖的部分,Harmony/Android/Web仍可響應事件,在 iOS 端無法響應事件。

多說一句:動態(tài)化作為一個跨端框架,會最大限度的抹平各端差異,但在有些系統(tǒng)特性上,還是會保持各端的默認實現(xiàn)。業(yè)務在使用時,可根據(jù)具體情況,具體處理。

六、布局問題分析

動態(tài)化在京東金融 App 里已經(jīng)大范圍使用,截止到 2024 年 8 月 26 日已有200+ 頁面,200+卡片使用動態(tài)化技術開發(fā)。在這個過程中與各業(yè)務一起解決了很多布局相關的問題。選擇幾個有共性的問題分享給大家。

1. 為什么沒有給item設置寬,item也沒有子視圖,但item卻有寬呢?

因為在動態(tài)化上視圖的主軸默認是column,align-items默認是stretch,因此item會填充父容器。

2. 為什么給item設置了寬,item顯示的寬卻是別的值?

這個情況就要具體分析了,如果你在設置了寬的情況下,還設置了flex:1;或者flex-grow:1;再或者flex-shrink等,item可能會被拉伸或者壓縮,導致寬度變化。也有可能其他item的縮放級別更高,優(yōu)先滿足其他item的顯示,當前item的尺寸也有可能被壓縮。

3. item既可以從container的設置中獲取尺寸,也可以被子item撐開獲取尺寸,也可以自己設置尺寸,還可以被拉伸或者壓縮。那item的尺寸最終是由誰來決定呢?

首先假設主軸為 column。container的align-items默認是stretch,因此item會填充父容器。但是如果item自身設置了寬,則會覆蓋stretch。如果item的align-self不是stretch,本身也沒有設置寬,但子視圖有寬,可以被子視圖撐開。如果自身設置了寬,則不受子視圖影響。

在主軸方向上如果item 本身沒有設置高,但子視圖有高,則可以子視圖撐開。如果自身設置了高,就不受子視圖的影響。如果自身設置了 flex-grow:1則會填充父視圖,同樣如果設置了 flex-shrink:1,空間不足則被壓縮,都會覆蓋自身設置的高。

最后:max-width 和 max-height 優(yōu)先級最高,如果觸發(fā)邊界條件,就會生效,從而覆蓋其他設置。

4. 如何讓n個item按照比例占據(jù)container的主軸空間?

對于這類比例問題,可設置所有item 的flex-basis 為 0,把自身空間全部收回,通過 flex-grow 分配對應比例即可。

5. 對于一個復雜的視圖,我該如何下手?

其實越是復雜的視圖實現(xiàn)的方式就越多,沒有固定的、標準的實現(xiàn)方式。下面說一下我的一點看法,我將視圖分為以下幾種場景:

1.如果視圖自身知道具體的寬高,那就直接設置,這是效率最高的方式。

2.如果視圖自身不知道寬高,但是父視圖有固定的尺寸,想辦法從父視圖獲取。

3.如果視圖自身不知道寬高,但子視圖有寬高,則可以靠子視圖撐開。

4.如果必要,使用 max-width 和 max-height 做最高層級的條件約束。

其他的情況一般都是以上四種情況的組合。只要理清視圖間約束條件,排除約束矛盾點,確定優(yōu)先級。先建立清晰的布局思路,明確視圖的尺寸來源,按照既定思路布局,不寫無效約束,一切就清晰自然。

七、寫在最后

動態(tài)化是一個涉及JavaScript、iOS、Android、Harmony、Java、Vue、Node、Webpack等眾多領域的綜合解決方案,我們有各個領域優(yōu)秀的小伙伴共同前行,大家如果想深入了解某個領域的具體實現(xiàn),可以隨時留言交流~!

審核編輯 黃宇

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內(nèi)容侵權或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • FLEX
    +關注

    關注

    0

    文章

    45

    瀏覽量

    15181
  • 鴻蒙
    +關注

    關注

    57

    文章

    2287

    瀏覽量

    42629
收藏 人收藏

    評論

    相關推薦

    鴻蒙實踐-JS虛擬機架構實現(xiàn)

    在Roma方案中,JS虛擬機是框架的核心,負責執(zhí)行動態(tài)化的JS代碼。在Android平臺采用了基于V8的J2V8,iOS平臺則使用了系統(tǒng)自帶的JSCore,而在HarmonyOS中,由于業(yè)界無
    的頭像 發(fā)表于 09-30 14:42 ?2208次閱讀
    <b class='flag-5'>鴻蒙</b><b class='flag-5'>跨</b><b class='flag-5'>端</b><b class='flag-5'>實踐</b>-JS虛擬機架構實現(xiàn)

    揭秘動態(tài)化框架在鴻蒙系統(tǒng)下的高性能解決方案

    平臺解決方案。 在研發(fā)團隊使用后可大幅降低研發(fā)人力成本;為業(yè)務提供實時觸達、A/B觸達等能力以提升業(yè)務投放效率;同時保障了C用戶優(yōu)秀的用戶體驗。 一、動態(tài)化框架原理
    的頭像 發(fā)表于 10-08 13:46 ?534次閱讀
    揭秘動態(tài)化<b class='flag-5'>跨</b><b class='flag-5'>端</b>框架在<b class='flag-5'>鴻蒙</b>系統(tǒng)下的高性能解決<b class='flag-5'>方案</b>

    最佳天線實踐布局指南以及天線調(diào)試程序

    有限的硬幣型電池)獲得的無線射程主要取決于天線的設計、塑料外殼以及良好的PCB布局。對于芯片和電源相同但布局和天線設計實踐不同的系統(tǒng),它們的RF(射頻)范圍變化超過50%也是正常的。本應用筆記
    發(fā)表于 05-21 08:51

    基于react-app配置移動自適應—淘寶彈性布局方案

    基于react-app配置移動自適應—淘寶彈性布局方案lib-flexible和postcss-px2rem實踐(750px設計稿)
    發(fā)表于 06-17 17:18

    如何理解鴻蒙OS是設備的?

    誰能幫忙解釋鴻蒙OS是怎樣實現(xiàn)平臺的?
    發(fā)表于 09-08 18:17

    鴻蒙介紹

    這份資料主要是對鴻蒙概念的掃盲,這里介紹鴻蒙的應用場景和技術框架,同時也有1000+頁,非常詳細的入門手冊。這份資料具體的內(nèi)容有:HarmonyOS快速入門手冊2.0通用設計基礎HarmonyOS入門文檔
    發(fā)表于 11-24 10:49

    鴻蒙輕簡歷應用開發(fā)嘗試

    `主要是鴻蒙輕應用概念的實踐,通過前端組件來做一個手機和電視版的個人簡歷。主要功能包括目錄、個人基本信息、個人能力與愛好、特長介紹、學歷證書、聯(lián)系方式。支持手機和電視兩種形式。主界面使用按鈕進行各個
    發(fā)表于 05-20 15:44

    鴻蒙生態(tài)-2022HDC鴻蒙應用與原子化服務全新技術呈現(xiàn)

    基礎的ArkTS語言介紹到高階分布式設備應用開發(fā)等一系列官方視頻課程,以及配套的開發(fā)文檔、SDK、API、示范代碼案例等。開發(fā)者通過學習本系列課程,參加考試符合標準,還可以獲得獲得官方鴻蒙證書與能力認證
    發(fā)表于 11-02 16:32

    鴻蒙應用ui布局

    請問,在用java開發(fā)鴻蒙應用布局UI時,怎么才能全屏布局(不顯示labelb標題)
    發(fā)表于 09-20 22:09

    DC-DC降壓轉(zhuǎn)換器電路布局與設計和實踐

    了解DC-DC降壓轉(zhuǎn)換器電路的最佳布局規(guī)范。在實現(xiàn)DC-DC降壓轉(zhuǎn)換器時,電路布局與設計同樣重要。布局不良會嚴重降低設計效果。本文將介紹一些最佳布局
    的頭像 發(fā)表于 07-11 16:46 ?1.2w次閱讀
    DC-DC降壓轉(zhuǎn)換器電路<b class='flag-5'>布局</b>與設計和<b class='flag-5'>實踐</b>

    鴻蒙強勢布局2021 庫克對蘋果做出戰(zhàn)略布局

    隨著華為對鴻蒙系統(tǒng)的進一步戰(zhàn)略布局,蘋果卻也作出了戰(zhàn)略布局,看似是在阻擋鴻蒙的發(fā)展。
    的頭像 發(fā)表于 01-20 11:24 ?1337次閱讀
    <b class='flag-5'>鴻蒙</b>強勢<b class='flag-5'>布局</b>2021 庫克對蘋果做出戰(zhàn)略<b class='flag-5'>布局</b>

    HarmonyOS分布式算力技術介紹

    功能上無法對智能化沉浸式體驗的應用提供全方位的支持,導致很多應用場景難以得到實現(xiàn)。 為了解決移動算力瓶頸,HarmonyOS分布式計算應運而生,給用戶帶來易協(xié)同、低延遲和高穩(wěn)定的分布式體驗。下面,我們將對
    的頭像 發(fā)表于 11-17 16:34 ?3483次閱讀
    HarmonyOS<b class='flag-5'>跨</b><b class='flag-5'>端</b>分布式算力技術<b class='flag-5'>介紹</b>

    鴻蒙應用如何喚起 QQ 安卓客戶進行授權

    因為鴻蒙系統(tǒng)剛出不久,官方的第三方登錄 SDK 還沒出來,下面就介紹下在鴻蒙應用中實現(xiàn) QQ 登錄的方法(支持喚起 QQ 安卓客戶進行授權)。
    的頭像 發(fā)表于 01-04 15:01 ?3594次閱讀

    鴻蒙開發(fā):應用組件設備交互(流轉(zhuǎn))【遷移】

    遷移的核心任務是將應用的當前狀態(tài)(包括頁面控件、狀態(tài)變量等)無縫遷移到另一設備,從而在新設備上無縫接續(xù)應用體驗。這意味著用戶在一臺設備上進行的操作可以在另一臺設備的相同應用中快速切換并無縫銜接。
    的頭像 發(fā)表于 06-11 17:10 ?942次閱讀
    <b class='flag-5'>鴻蒙</b>開發(fā):應用組件<b class='flag-5'>跨</b>設備交互(流轉(zhuǎn))【<b class='flag-5'>跨</b><b class='flag-5'>端</b>遷移】

    鴻蒙實踐-長列表解決方案和性能優(yōu)化

    平臺都非常重要。HarmonyOS和iOS類似也提供了自己的解決方案。Roma(羅碼)作為端平臺,在此基礎上進行了具體的實踐。在實踐過程中,遇到了各種問題和挑戰(zhàn),經(jīng)歷了ArkTS+C
    的頭像 發(fā)表于 09-23 15:26 ?225次閱讀
    <b class='flag-5'>鴻蒙</b><b class='flag-5'>跨</b><b class='flag-5'>端</b><b class='flag-5'>實踐</b>-長列表解決<b class='flag-5'>方案</b>和性能優(yōu)化