鴻蒙Banner圖一多適配不同螢幕

龙儿筝發表於2024-11-04

認識一多

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

img

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

Banner圖一多適配

我們在使用Banner圖時,會發現在中大屏裝置上,Banner的寬度太大,當我們將高度固定時,在大屏裝置上,高度又太小,圖片裁剪嚴重。若寬高採用比例設定,高度又太大,在不同的螢幕上要麼太小或太大,顯示效果都不是很理想。

Banner有一個屬性displayCount,用來控制一屏顯示多少個元件,我們在小屏裝置上顯示一張圖片,在中大屏裝置上一屏顯示2張圖片。再使用aspectRatio設定合適的寬高比,就能達到我們想要的效果了。

我們現在只需要判斷裝置是小屏還是中大屏就可以了,這裡藉助GridRow柵格元件的斷點能力,針對小屏和非小屏裝置,設定不同的displayCount和aspectRatio就可以了,實現小原始碼如下。

@ComponentV2
struct Index {
  @Local breakPoint: string = 'unknown'
  @Local images: string[] = []

  @Computed
  get isSm(): boolean {
    return this.breakPoint === 'sm'
  }

  build() {
    Column() {
          GridRow({
            columns: 1,
            breakpoints: { reference: BreakpointsReference.WindowSize }
          }) {
            GridCol() {
              Swiper() {
                Repeat(this.images).each((data: Readonly<RepeatItem<string>>) => {
                  Image(data.item)
                }).key((item) => item)
              }
              .width('100%')
              .height('100%')
              .loop(false)
              .duration(1000)
              .autoPlay(false)
              .indicatorInteractive(true)
              .itemSpace(this.isSm ? 0 : 32)
              .displayCount(this.isSm ? 1 : 2)
              .indicator(new DotIndicator().itemWidth(8)
                .itemHeight(8)
                .selectedItemWidth(12)
                .selectedItemHeight(8)
                .color($r('app.color.divider_color'))
                .selectedColor($r('app.color.brand_color')))
            }
          }.width('100%').aspectRatio(this.isSm ? 2.5 : 4.5).onBreakpointChange((point) => {
            this.breakPoint = point
          })
        }.width('100%').justifyContent(FlexAlign.Start)
  }
}

在不同裝置的顯示效果如下。

相關文章