鸿蒙Next(五) 栅格布局

255 阅读2分钟

1、使用场景

a、多终端适配
  • 适配手机、平板、智慧屏等不同屏幕尺寸设备,通过栅格系统自动调整元素比例与间距,避免碎片化设计。
  • 典型场景:电商商品列表(手机显示3列,平板显示5列)、仪表盘数据卡片布局。
b、复杂界面结构化
  • 解决嵌套布局混乱问题,例如表单、设置页面的多级排列,或组合卡片(图文+按钮)的精准对齐。
  • 支持跨设备交互设计,如车机中控屏与手机联动的信息流布局。
c、动态响应式设计
  • 横竖屏切换时自动重组内容(如视频播放页的评论列表从单列变为多列)。
  • 结合鸿蒙「自适应布局」能力,根据屏幕比例动态调整栅格列数(如折叠屏展开后从4列增至8列)。

2、示例:

import { BPConstants, BPType, CommonConstants, ResourceUtil } from '@ohos/commons';
import { IconInfo, IconInfoViewModel } from '../viewmodel/IconInfoViewModel';

// 类别(首页)

@Component
export struct Categories {
  @StorageLink('currentBreakpoint') currentBP: string = BPConstants.LG;
  @State isNextCategory: boolean = false; //是否为分类第二页
  private categoryIcons: IconInfo[] = new IconInfoViewModel().getCategoryList();

  build() {
    Stack() {

      // 线性渐变
      Row()
        .width('100%').height(60)
        .linearGradient({
          //线性渐变相关配置
          direction: GradientDirection.Bottom, //渐变方向 - 向下(Top Bottom Left Right)
          colors: [['#BCD1EF', 0.0], ['#FFFFFF', 1.0]] //渐变颜色梯度,可以设置多个
        })//设置圆角
        .border({
          //圆角半径
          radius: {
            topLeft: 20, //左上角圆角半径
            topRight: 20 //右上角圆角半径
          }
        })

      //列表
      Column() {

        GridRow({
          columns: 10, //列总数 (实现一行显示5个item:columns设置10 span设置2就行了)
        }) {
          ForEach(this.categoryIcons, (item: IconInfo) => {

            GridCol({
              span: 2 //跨距:子项所占的列格
            }) {
              Column() {
                Image(item.getIcon())//根据设备类型匹配对应的三个值 (这三个值是范型,传任何类型都行,最终都会返回当前设备对应的值)
                  .height(new BPType(40, 64, 68).getValue(this.currentBP))
                Text(item.getInfo())
                  .fontSize($r('app.float.category_text_font'))
                  .fontWeight(FontWeight.Normal)
                  .lineHeight($r('app.float.category_text_line'))
              }
            }
          })
        }.height("100%").width("100%")

      }
      .width(CommonConstants.Full_Percent)
      .height(new BPType(126, 180, 200).getValue(this.currentBP))
      .padding({
        left: ResourceUtil.getPageColPadding().getValue(this.currentBP)
      })
      .margin({
        top: 25,
        bottom: $r('app.float.category_col_margin'),
        right: this.currentBP === BPConstants.SM ? $r("app.float.category_col_margin_sm") : 0
      })
    }
    .align(Alignment.Top) //对齐方式
    .margin({ top: -15 }) //(上移挡住了轮播图的指示器)
  }
}