一、一多開發核心概念(1+8+N模式)
? ? ? ? 目標:一次開發多端部署 解決的問題:
????????????????1、界面級一多:適配不同屏幕尺寸
????????????????2、功能級一多:設備功能兼容性處理(CanIUser)
????????????????3、工程級一多:項目架構管理(三成架構HAP、HAR、HSP)
二、界面級一多解決方法
1、自適應布局
能力 | 核心屬性/組件 | 代碼示例 |
拉伸 | flexGrow/flexShrink | .flexGrow(1).flexShrink(1) |
均分 | justifyContent: SpaceEvenly | Row().justifyContent(FlexAlign.SpaceEvenly) |
占比 | layoutWeight 或百分比寬高 | .width('50%').layoutWeight(1) |
縮放 | aspectRatio | .aspectRatio(1.5) |
延伸 | List/Scroll + Row | List().listDirection(Axis.Horizontal) |
隱藏 | displayPriority | .displayPriority(2) |
折行 | FlexWrap.Wrap | Flex({ wrap: FlexWrap.Wrap }) |
2、響應式布局
? ? ? ? 2-1、斷點系統
斷點 | 范圍(vp) | 典型設備 |
xs | [0, 320) | 智能手表 |
sm | [320, 600) | 手機豎屏 |
md | [600, 840) | 折疊屏/橫屏 |
lg | [840, +∞) | 平板/PC |
// 在Ability中監聽窗口變化
windowObj.on('windowSizeChange', (size) => {const widthVp = size.width / density;AppStorage.set('currentBreakpoint', calculateBreakpoint(widthVp));
});
2-2、媒體查詢
// 創建監聽器
const listener = mediaquery.matchMediaSync('(320vp<=width<600vp)');
// 注冊回調
listener.on('change', (res) => {if (res.matches) AppStorage.set('breakpoint', 'sm');
});
// 移除監聽
listener.off('change');
2-3柵格布局
GridRow({columns: { sm: 4, md: 8, lg: 12 },gutter: 10
})
/*--------------------------------------------*/
//GridRow:定義行布局規則
GridRow({columns: { sm: 4, md: 8, lg: 12 },gutter: 10
})
/*--------------------------------------------*/
//GridCol:定義列占比與偏移
GridCol({span: { sm: 2, md: 4 },offset: { md: 1 }
})
場景 | 推薦方案 | 優勢 |
微調元素尺寸 | 自適應布局(占比/拉伸) | 簡單高效,代碼侵入性低 |
多設備顯隱邏輯 | 響應式布局(媒體查詢) | 精確控制不同斷點下的UI表現 |
復雜多列布局 | 柵格系統 | 內置響應規則,維護性強 |
全局斷點狀態管理 | BreakpointSystem工具 | 統一管理斷點,避免重復監聽 |
3、界面級一多斷點
import window from '@ohos.window'
import display from '@ohos.display'
import UIAbility from '@ohos.app.ability.UIAbility'export default class EntryAbility extends UIAbility {private windowObj?: window.Windowprivate curBp: string = ''//...// 根據當前窗口尺寸更新斷點private updateBreakpoint(windowWidth: number) :void{// 將長度的單位由px換算為vplet windowWidthVp = windowWidth / display.getDefaultDisplaySync().densityPixelslet newBp: string = ''if (windowWidthVp < 320) {newBp = 'xs' // 超小屏} else if (windowWidthVp < 600) {newBp = 'sm' // 小屏} else if (windowWidthVp < 840) {newBp = 'md' // 中屏} else {newBp = 'lg' // 大屏}if (this.curBp !== newBp) {this.curBp = newBp// 使用狀態變量記錄當前斷點值AppStorage.setOrCreate('currentBreakpoint', this.curBp)}}onWindowStageCreate(windowStage: window.WindowStage) :void{windowStage.getMainWindow().then((windowObj) => {this.windowObj = windowObj// 獲取應用啟動時的窗口尺寸this.updateBreakpoint(windowObj.getWindowProperties().windowRect.width)// 注冊回調函數,監聽窗口尺寸變化windowObj.on('windowSizeChange', (windowSize)=>{this.updateBreakpoint(windowSize.width)})});// ...}//...
}
- 技術棧:
- 鴻蒙特定 API:基于鴻蒙系統的
@ohos.window
、@ohos.display
和@ohos.app.ability.UIAbility
模塊進行開發,充分利用鴻蒙系統提供的窗口管理、顯示信息獲取以及應用能力相關的原生 API。- 核心點:
- 窗口尺寸監聽:在
onWindowStageCreate
方法中,通過windowStage.getMainWindow().then
獲取主窗口對象,隨后利用windowObj.on('windowSizeChange', ...)
注冊回調函數,實時監聽窗口尺寸變化,這是實現屏幕適配的關鍵起始步驟。- 斷點計算與更新:
updateBreakpoint
方法將獲取到的窗口寬度從像素(px
)換算為虛擬像素(vp
),根據不同的vp
范圍確定對應的斷點值(xs
、sm
、md
、lg
)。當計算出的新斷點與當前斷點不同時,更新當前斷點并通過AppStorage.setOrCreate
方法記錄在狀態變量中,以便應用其他部分根據斷點值進行不同的布局或功能調整。
三、總結?
????????本文圍繞 “一多開發” 這一核心概念展開,著重探討了其在界面級的實現方式。“一多開發” 旨在達成一次開發多端部署,解決界面、功能及工程等層面的適配與管理問題。
????????在界面級,通過自適應布局、響應式布局兩種主要方式實現對不同屏幕尺寸的適配。自適應布局借助如flexGrow
、justifyContent
等多種屬性和組件,能簡單高效地微調元素尺寸;響應式布局則通過斷點系統、媒體查詢和柵格布局,可更精準地控制不同設備下的 UI 表現,滿足多設備顯隱邏輯和復雜多列布局等場景需求。
????????結合提供的鴻蒙開發代碼示例,其基于鴻蒙特定 API 實現了窗口尺寸監聽與斷點計算更新,這是界面適配的關鍵技術點。通過監聽窗口變化獲取尺寸信息,換算為vp
后確定斷點值并記錄,為應用根據不同屏幕尺寸調整布局和功能提供依據。