Harmony之路:UI构建之基石——ArkUI声明式组件与布局

一、引入:从命令式到声明式的思维转变

在传统命令式UI开发中,我们需要一步步告诉系统如何创建和更新UI元素,而ArkUI的声明式开发范式让我们只需描述"UI应该是什么样子",系统会自动处理渲染和更新。这种转变不仅提升了开发效率,更让代码逻辑更加清晰易懂。

二、讲解:三大核心布局容器实战

1. Column垂直布局——纵向排列的基石

Column是垂直方向排列的容器组件,主轴为垂直方向,交叉轴为水平方向。它是构建列表、表单等垂直结构界面的首选。

基础用法示例:

@Entry
@Component
struct ColumnExample {
  build() {
    Column({ space: 20 }) {  // 设置子元素垂直间距20vp
      Text('标题')
        .fontSize(24)
        .fontWeight(FontWeight.Bold)
      
      Text('副标题')
        .fontSize(16)
        .fontColor(Color.Gray)
      
      Button('确认按钮')
        .width('80%')
        .height(40)
        .backgroundColor(Color.Blue)
        .onClick(() => {
          console.log('按钮被点击')
        })
    }
    .width('100%')
    .height('100%')
    .padding(20)
    .justifyContent(FlexAlign.Center)  // 主轴居中对齐
    .alignItems(HorizontalAlign.Center) // 交叉轴居中对齐
  }
}

关键属性详解:

  • space:子元素在主轴方向的间距,支持数字或百分比
  • justifyContent:主轴对齐方式(FlexAlign.Start/Center/End/SpaceBetween/SpaceAround/SpaceEvenly)
  • alignItems:交叉轴对齐方式(HorizontalAlign.Start/Center/End)

2. Row水平布局——横向排列的利器

Row是水平方向排列的容器组件,主轴为水平方向,交叉轴为垂直方向。适用于导航栏、按钮组等横向布局场景。

实战示例:底部导航栏

@Entry
@Component
struct BottomNavigation {
  @State currentIndex: number = 0
  
  build() {
    Column() {
      // 内容区域
      Column() {
        Text('页面内容')
          .fontSize(20)
      }
      .layoutWeight(1)  // 占据剩余空间
      
      // 底部导航
      Row({ space: 0 }) {
        ForEach([0, 1, 2], (index) => {
          Column() {
            Image(this.currentIndex === index ? 
              $r('app.media.icon_selected') : 
              $r('app.media.icon_normal'))
              .width(24)
              .height(24)
            Text(['首页', '发现', '我的'][index])
              .fontSize(12)
              .fontColor(this.currentIndex === index ? 
                Color.Blue : Color.Gray)
          }
          .width('33%')
          .height(60)
          .onClick(() => {
            this.currentIndex = index
          })
        })
      }
      .width('100%')
      .backgroundColor(Color.White)
      .border({ width: 1, color: Color.Gray })
    }
    .width('100%')
    .height('100%')
  }
}

布局权重技巧:

使用layoutWeight属性可以让子组件按比例分配剩余空间,这是实现自适应布局的关键。

3. Stack层叠布局——叠加效果的艺术

Stack允许子元素在Z轴方向堆叠,后添加的元素会覆盖在前面的元素上,适用于弹窗、悬浮按钮等场景。

弹窗实现示例:

@Entry
@Component
struct StackExample {
  @State isShowDialog: boolean = false
  
  build() {
    Stack() {
      // 主页面内容
      Column() {
        Text('主页面')
          .fontSize(24)
        Button('显示弹窗')
          .onClick(() => {
            this.isShowDialog = true
          })
      }
      .width('100%')
      .height('100%')
      
      // 弹窗层(条件渲染)
      if (this.isShowDialog) {
        Column() {
          Text('这是一个弹窗')
            .fontSize(20)
          Button('关闭')
            .onClick(() => {
              this.isShowDialog = false
            })
        }
        .width(300)
        .height(200)
        .backgroundColor(Color.White)
        .cornerRadius(10)
        .position({ x: '50%', y: '50%' })
        .margin({ left: -150, top: -100 })  // 居中定位
        .zIndex(100)  // 设置层级
      }
    }
    .width('100%')
    .height('100%')
  }
}

核心特性:

  • zIndex:控制子元素的层级,值越大越靠上
  • position:绝对定位,设置相对于父容器的偏移量
  • alignContent:设置子元素的对齐方式

三、总结:布局设计的最佳实践

✅ 核心要点回顾

  1. Column与Row是基础:掌握主轴和交叉轴的概念,灵活运用justifyContent和alignItems实现精准对齐
  2. Stack实现叠加效果:通过zIndex和position实现弹窗、悬浮按钮等复杂布局
  3. layoutWeight分配空间:使用权重布局让界面自适应不同屏幕尺寸

⚠️ 避坑指南

  • 避免过度嵌套:布局嵌套超过3层会影响性能,建议使用Flex或Grid替代
  • 合理使用百分比:使用'100%'、'50%'等相对单位,而非固定像素值
  • 注意zIndex层级:Stack中多个子元素叠加时,确保重要内容有足够高的层级

🎯 实战建议

  1. 从简单开始:先用Column和Row搭建页面框架,再逐步添加复杂布局
  2. 组件化思维:将重复的布局结构封装成自定义组件,提高代码复用率
  3. 多设备预览:在DevEco Studio中切换不同设备模拟器,验证布局的响应式效果

下一步预告:在第四篇中,我们将深入学习@State状态管理,让UI能够响应数据变化,实现真正的动态界面。

posted @ 2025-12-23 23:00  蓝莓Reimay  阅读(2)  评论(0)    收藏  举报