鴻蒙適配一多搭建首頁框架

龙儿筝發表於2024-11-03

隨著終端裝置形態日益多樣化,分散式技術逐漸打破單一硬體邊界,一個應用或服務,可以在不同的硬體裝置之間隨意呼叫、互助共享,讓使用者享受無縫的全場景體驗。而作為應用開發者,廣泛的裝置型別也能為應用帶來廣大的潛在使用者群體。但是如果一個應用需要在多個裝置上提供同樣的內容,則需要適配不同的螢幕尺寸和硬體,開發成本較高。HarmonyOS系統面向多終端提供了“一次開發,多端部署”(後文中簡稱為“一多”)的能力,讓開發者可以基於一種設計,高效構建多端可執行的應用。
img

“一多”建議從最初的設計階段開始就拉通多裝置綜合考慮。考慮實際智慧終端裝置種類繁多,設計師無法針對每種具體裝置各自出一份UX設計圖。“一多”建議從裝置螢幕寬度的維度,將裝置劃分為六大類。設計師只需要針對這六大類裝置做設計,而無需關心具體的裝置形態。

裝置型別 斷點名稱
超小裝置 xs
小裝置 sm
中裝置 md
大裝置 lg
特大裝置 xl
超大裝置 xxl

GridRow和Tab實現首頁適配一多

首頁我們一般使用Tab來佈局,包含4到6個子頁面,在中小屏手機上選項卡在底部,Tab使用上下排版,例如手機,摺疊屏和豎向平板等等,但像橫向平板和2in1裝置採用上下排版就不合適了,推薦採用左右排版。Tab的vertical屬性可以設定Tab是上下排版還是左右排版。

現在我們只需要判斷出裝置是中小屏還是大屏裝置,系統給我們提供了GridRow柵格元件,我們在柵格元件的onBreakpointChange中可以獲取到當前裝置屬於哪一種。具體實現如下

@ComponentV2
export struct HomePage {
  @Local breakPoint: string = 'unknown'
  @Local selectIndex: number = 0
  readonly items: TabItemBean[] = [
    { name: '推薦', icon: $r('sys.symbol.house') },
    { name: '體系', icon: $r('sys.symbol.puzzle') },
    { name: '導航', icon: $r('sys.symbol.paperplane') },
    { name: '專案', icon: $r('sys.symbol.square_grid_2x2') },
    { name: '我的', icon: $r('sys.symbol.person') }
  ]

  @Computed
  get isLg(): boolean {
    return this.breakPoint === 'lg'
  }

  @Builder
  tabItemBuilder(item: TabItemBean, index: number) {
    Column() {
      SymbolGlyph(item.icon)
        .fontSize(24)
        .fontColor([this.selectIndex === index ? $r('app.color.brand_color') : $r('app.color.dialog_content')])
      Text(item.name)
        .fontSize(14)
        .fontColor(this.selectIndex === index ? $r('app.color.brand_color') : $r('app.color.dialog_content'))
    }.onClick(() => {
      this.selectIndex = index
    })
  }

  build() {
    GridRow({
      columns: 1,
      breakpoints: { reference: BreakpointsReference.WindowSize }
    }) {
      GridCol() {
        Tabs({ index: $$this.selectIndex }) {
          Repeat<TabItemBean>(this.items).each((data: Readonly<RepeatItem<TabItemBean>>) => {
            TabContent() {
              Text(data.item.name)
            }.tabBar(this.tabItemBuilder(data.item, data.index))
          }).key((data: Readonly<TabItemBean>) => data.name)
        }
        .vertical(this.isLg)
        .barPosition(this.isLg ? BarPosition.Start : BarPosition.End)
      }
    }.width('100%')
    .height('100%')
    .onBreakpointChange((point) => {
      this.breakPoint = point
    })
  }
}

在中小屏裝置上,Tab選項卡在底部,選項卡採用橫向排版;在大屏裝置上,Tab選項卡在左邊,選項卡採用豎向排版,效果如圖。

相關文章