鸿蒙HarmonyOS NEXT开发:一次开发,多端部署(界面级)常见布局解决方案

虽然不同应用的页面千变万化,但对其进行拆分和分析,页面中的很多布局场景是相似的。本小节将介绍如何借助自适应布局、响应式布局以及常见的容器类组件,实现应用中的典型布局场景。

1、顶部单张大图

顶部背景图被拉伸时,可以通过设置背景图片的backgroundImageSize属性,使得图片大小能够合理显示,达到适配效果。

微信图片_20250109103301.png

参考代码

@Entry
@Component
struct FQPage {

  build() {
    Column() {
      // 设置背景图片的backgroundImageSize属性,使得图片大小能够合理显示
      Column()
        .width('100%')
        .height(300)
        .backgroundColor('#ccc')
        .backgroundImage($r('app.media.1'))
        .backgroundImageSize(ImageSize.Cover)
        .backgroundImagePosition(Alignment.Center)
    }
    .height('100%')
    .width('100%')
    .backgroundColor('#F1F3F5')
  }
}

2、网格列表

在大屏上,Listitem内容会过大,页面整体浏览内容减少。可通过以下两种方法解决:

微信图片_20250109103202.png
  • 设置List列的最小宽度和最大宽度,使List组件根据宽度自适应决定列数。
  • 借助栅格行组件GridRow,调整不同的断点下List组件的宽度。
@Entry
@Component
struct FQPage {
  @State data: Resource[] = new Array(5).fill($r("app.media.1"))
  @State breakPoint: string = 'sm'

  build() {
    GridRow() {
      GridCol({ span: { sm: 12, md: 12, lg: 12 } }) {
        List({ space: 24 }) {
          ForEach(this.data, (item: Resource) => {
            ListItem() {
              Image(item).margin({ left: 12, right: 12 })
            }
          })
        }
        // 设置列最小宽度和最大宽度
        .lanes({ minLength: 300, maxLength: 360 }).padding(12)
      }
    }.onBreakpointChange((breakpoint: string) => {
      this.breakPoint = breakpoint
    })
  }
}
  • 根据断点设置List列数。
@Entry
@Component
struct FQPage {
  @State data: Resource[] = new Array(5).fill($r("app.media.1"))
  @State breakPoint: string = 'sm'

  build() {
    GridRow() {
      GridCol({ span: { sm: 12, md: 12, lg: 12 } }) {
        List({ space: 24 }) {
          ForEach(this.data, (item: Resource) => {
            ListItem() {
              Image(item).margin({ left: 12, right: 12 })
            }
          })
        }
        // 根据断点设置List列数
        .lanes(this.breakPoint === 'sm' ? 1 : this.breakPoint === 'md' ? 2 : 3)
        .padding(12)
      }
    }.onBreakpointChange((breakpoint: string) => {
      this.breakPoint = breakpoint
    })
  }
}

3、运营横幅(Banner)

在大屏上,Swiper图片显示内容过大,可以通过增加Swiper展示图片数来调整图片显示大小。外层可以使用栅格组件GridRow,通过调用OnBreakpointChange事件,调整不同的断点下Swiper的前后边距,实现在不同屏幕尺寸上的显示不同Swiper图片数。

不同断点下,运营横幅中展示的图片数量不同。只需要结合响应式布局,配置不同断点下Swiper组件的displayCount属性,即可实现目标效果。

微信图片_20250109103125.png
@Entry
@Component
struct FQPage {

  @State data: Resource[] = new Array(6).fill($r("app.media.1"))
  @State breakPoint: string = 'sm'

  build() {
    Column() {
      Row() {
        GridRow() {
          GridCol({ span: { sm: 12, md: 12, lg: 12 } }) {
            Swiper() {
              ForEach(this.data, (item: Resource) => {
                Image(item)
                  .width('100%')
                  .height(200)
                  .objectFit(ImageFit.Cover)
              })
            }
            // 根据断点设置Swiper图片数量
            .displayCount(this.breakPoint === 'lg' ? 2 : 1, true)
            .autoPlay(true)
            .loop(true)
            .width('100%')
            .itemSpace(24)
            // 根据断点设置Swiper前后边距
            .prevMargin(this.breakPoint === 'md' ? 150 : 0)
            .nextMargin(this.breakPoint === 'md' ? 150 : 0)
          }
        }.onBreakpointChange((breakpoint: string) => {
          this.breakPoint = breakpoint
        })
      }
    }
    .height('100%')
    .width('100%')
    .backgroundColor('#F1F3F5')
  }
}

4、信息流单张图片

针对信息流单张图片过大的情况,设置aspectRatio和constrainSize属性,可以通过对图片的布局和尺寸进行约束,达到适配效果。

微信图片_20250109103044.png
@Entry
@Component
struct FQPage {
  @State breakPoint: string = 'sm'

  build() {
    Column() {
      GridRow(){
        GridCol({ span: { sm: 12, md: 12, lg: 12 } }){
          Column(){
            Text('一次开发,多端部署,让开发者可以基于一种设计,高效构建多端可运行的应用。一次开发,多端部署,让开发者可以基于一种设计,高效构建多端可运行的应用。')
            // 设置aspectRatio和constrainSize属性,可以对图片的布局和尺寸进行约束
            Image($r('app.media.1'))
              .width('50%')
              .aspectRatio(1)
              .constraintSize({ maxWidth: 320, minWidth: 180 })
            Text('一次开发,多端部署,让开发者可以基于一种设计,高效构建多端可运行的应用。一次开发,多端部署,让开发者可以基于一种设计,高效构建多端可运行的应用。')
          }.alignItems(HorizontalAlign.Start)

        }
      }.onBreakpointChange((breakpoint: string) => {
        this.breakPoint = breakpoint
      })
    }
    .height('100%')
    .width('100%')
    .backgroundColor('#F1F3F5')
  }
}

5、信息流4宫格图片

在大屏上,Grid组件里的4宫格图片大小过大,页面浏览区域变少。可以借助栅格行组件GridRow来调整不同的断点下Grid的宽度,解决大屏上Grid组件4宫格图片过大的问题。

微信图片_20250109102910.png
@Entry
@Component
struct FQPage {
  @State data: Resource[] = new Array(4).fill($r("app.media.1"))
  @State breakPoint: string = 'sm'

  build() {
    Column() {
      GridRow() {
        GridCol({ span: { sm: 12, md: 12, lg: 12 } }) {
          Column({ space: 10 }) {
            Text('一次开发,多端部署,让开发者可以基于一种设计,高效构建多端可运行的应用。在大屏上,Grid组件里的4宫格图片大小过大,页面浏览区域变少。可以借助栅格行组件GridRow来调整不同的断点下Grid的宽度,解决大屏上Grid组件4宫格图片过大的问题。')
              .lineHeight(24)
              .fontSize(15)
            Grid() {
              ForEach(this.data, (item: Resource) => {
                GridItem() {
                  Image(item)
                    .width('100%')
                    .aspectRatio(1)
                }
              })
            }.columnsTemplate('1fr 1fr')
            .columnsGap(10)
            .rowsGap(10)
            // 根据断点设置Grid宽度
            .width(this.breakPoint === 'sm' ? '100%' : this.breakPoint === 'md' ? '60%' : '40%')
          }.width('100%')
          .alignItems(HorizontalAlign.Start)
        }
      }.onBreakpointChange((breakpoint: string) => {
        this.breakPoint = breakpoint
      })
    }
    .height('100%')
    .width('100%')
    .padding(10)
    .backgroundColor('#F1F3F5')
  }
}

6、信息流9宫格图片

在大屏上,Grid组件里的9宫格图片大小过大,页面整体浏览内容减少,可以设置Grid组件宽度和宽高比,使Grid组件保持固定大小,不会随着屏幕尺寸变化而变化。

微信图片_20250109102948.png
@Entry
@Component
struct FQPage {
  @State data: Resource[] = new Array(9).fill($r("app.media.1"))

  build() {
    Column() {
      Column({ space: 10 }) {
        Text('一次开发,多端部署,让开发者可以基于一种设计,高效构建多端可运行的应用。在大屏上,Grid组件里的9宫格图片大小过大,页面整体浏览内容减少,可以设置Grid组件宽度和宽高比,使Grid组件保持固定大小,不会随着屏幕尺寸变化而变化。')
          .lineHeight(24)
          .fontSize(15)
        Grid() {
          ForEach(this.data, (item: Resource) => {
            GridItem() {
              Image(item)
                .width('100%')
                .aspectRatio(1)
            }
          })
        }
        .columnsTemplate('1fr 1fr 1fr')
        .columnsGap(10)
        .rowsGap(10)
        // 设置固定宽度和宽高比
        .width(360)
        .aspectRatio(1)
      }.width('100%')
      .alignItems(HorizontalAlign.Start)
    }
    .height('100%')
    .width('100%')
    .padding(10)
    .backgroundColor('#F1F3F5')
  }
}
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容