【HarmonyOS5】Column和Row组件详解

在这里插入图片描述

⭐本期内容:【HarmonyOS5】Column和Row组件详解
🏆系列专栏:鸿蒙HarmonyOS:探索未来智能生态新纪元



前言

在HarmonyOS的ArkUI框架中,布局是构建应用界面的基础。其中ColumnRow是两个最常用的线性布局容器组件,它们帮助开发者以简单灵活的方式组织和排列界面元素。


基本概念

在了解Column和Row之前,我们需要先理解ArkUI布局中的两个重要概念:主轴交叉轴

  • 主轴:指布局容器的主要排列方向

    • Column的主轴是垂直方向(从上到下)
    • Row的主轴是水平方向(从左到右)
  • 交叉轴:与主轴垂直的轴

    • Column的交叉轴是水平方向
    • Row的交叉轴是垂直方向

在这里插入图片描述

Column组件

Column是一个沿垂直方向布局的容器组件,它将子组件从上到下依次排列。

Column() {
  Text('第一项')
  Text('第二项')
  Text('第三项')
  Text('第四项')
  Text('第五项')
}

在这里插入图片描述

Row组件

Row是一个沿水平方向布局的容器组件,它将子组件从左到右依次排列。

Row() {
  Text('第一项')
  Text('第二项')
  Text('第三项')
  Text('第四项')
  Text('第五项')
}

在这里插入图片描述

主要属性

Column和Row的接口定义

// Column接口定义
interface ColumnInterface {
  (value?: { space?: string | number }): ColumnAttribute;
}

// Row接口定义
interface RowInterface {
  (value?: { space?: string | number }): RowAttribute;
}

两者都有一个可选参数space,表示子组件在主轴方向上的间距。

对齐方式

Column和Row提供了两种对齐方式的属性:

  1. justifyContent:控制子组件在主轴方向上的对齐方式
  2. alignItems:控制子组件在交叉轴方向上的对齐方式

justifyContent属性

justifyContent接受一个FlexAlign类型的参数,用于设置子组件在主轴方向上的排列方式。FlexAlign定义了以下几种类型:

  • FlexAlign.Start:元素在主轴方向首端对齐,第一个元素与容器起始端对齐,后续元素依次排列
  • FlexAlign.Center:元素在主轴方向中心对齐,所有元素居中,首尾距离相等
  • FlexAlign.End:元素在主轴方向尾部对齐,最后一个元素与容器末端对齐,其他元素依次向前排列
  • FlexAlign.SpaceBetween:元素在主轴方向均匀分布,首尾元素分别与容器两端对齐,中间元素间距相等
  • FlexAlign.SpaceAround:元素在主轴方向均匀分布,首尾元素与容器边缘的距离是元素间距的一半
  • FlexAlign.SpaceEvenly:元素在主轴方向等间距分布,包括首尾元素与容器边缘的距离也相等
Column() {
  Text('文本1').width('80%').height(50).backgroundColor('#FF3333')
  Text('文本2').width('60%').height(50).backgroundColor('#33FF33')
  Text('文本3').width('40%').height(50).backgroundColor('#3333FF')
}
.width('100%')
.height(300)
.backgroundColor('#EEEEEE')
.justifyContent(FlexAlign.SpaceBetween)

在这里插入图片描述

alignItems属性

Column容器的alignItems属性

Column容器的alignItems接受一个HorizontalAlign类型的参数,用于设置子组件在水平方向(交叉轴)上的对齐方式:

  • HorizontalAlign.Start:子组件在水平方向上按照起始端对齐
  • HorizontalAlign.Center(默认值):子组件在水平方向上居中对齐
  • HorizontalAlign.End:子组件在水平方向上按照末端对齐
Column() {
  Text('文本1').width('60%').height(50).backgroundColor('#FF3333')
  Text('文本2').width('80%').height(50).backgroundColor('#33FF33')
  Text('文本3').width('40%').height(50).backgroundColor('#3333FF')
}
.width('100%')
.height(300)
.backgroundColor('#EEEEEE')
.alignItems(HorizontalAlign.Start)
Row容器的alignItems属性

Row容器的alignItems接受一个VerticalAlign类型的参数,用于设置子组件在垂直方向(交叉轴)上的对齐方式:

  • VerticalAlign.Top:子组件在垂直方向上居顶部对齐
  • VerticalAlign.Center(默认值):子组件在垂直方向上居中对齐
  • VerticalAlign.Bottom:子组件在垂直方向上居底部对齐
Row() {
  Text('文本1').width(80).height('40%').backgroundColor('#FF3333')
  Text('文本2').width(80).height('60%').backgroundColor('#33FF33')
  Text('文本3').width(80).height('80%').backgroundColor('#3333FF')
}
.width('100%')
.height(300)
.backgroundColor('#EEEEEE')
.alignItems(VerticalAlign.Bottom)

在这里插入图片描述

间距设置

通过space属性,可以设置子组件在排列方向上的间距,使各子组件等间距排列。

Column({ space: 20 }) {
  Text('文本1').width('90%').height(80).backgroundColor('#FF3333')
  Text('文本2').width('90%').height(80).backgroundColor('#33FF33')
  Text('文本3').width('90%').height(80).backgroundColor('#3333FF')
}
.width('100%')
.backgroundColor('#EEEEEE')

在这里插入图片描述

⚠️ 注意:如果设置了space属性,justifyContent属性将不再生效。

自适应拉伸

在实际开发中,我们常常需要让组件根据屏幕大小自适应调整。

使用百分比宽高

@Entry
@Component
struct WidthExample {
  build() {
    Column() {
      Row() {
        Column() {
          Text('左侧 width 20%')
            .textAlign(TextAlign.Center)
        }.width('20%').backgroundColor('#ffb3def5').height('100%')

        Column() {
          Text('中间 width 50%')
            .textAlign(TextAlign.Center)
        }.width('50%').backgroundColor('#ff3397be').height('100%')

        Column() {
          Text('右侧 width 30%')
            .textAlign(TextAlign.Center)
        }.width('30%').backgroundColor('#ff4880e2').height('100%')
      }.backgroundColor('#ff090660').height('30%')
    }
  }
}

在这里插入图片描述

使用layoutWeight属性

layoutWeight属性允许子组件按照指定的权重比例分配剩余空间:

@Entry
@Component
struct LayoutWeightExample {
  build() {
    Column() {
      Text('比例为 1:2:3').width('100%')
      Row() {
        Column() {
          Text('layoutWeight(1)')
            .textAlign(TextAlign.Center)
        }.layoutWeight(1).backgroundColor('#ff679bd9').height('100%')

        Column() {
          Text('layoutWeight(2)')
            .textAlign(TextAlign.Center)
        }.layoutWeight(2).backgroundColor('#ff2e84ea').height('100%')

        Column() {
          Text('layoutWeight(3)')
            .textAlign(TextAlign.Center)
        }.layoutWeight(3).backgroundColor('#ff155b92').height('100%')
      }.backgroundColor('#FFD306').height('30%')
    }
  }
}

在这里插入图片描述

使用Blank组件

Blank组件可以在线性布局中填充剩余空间。

@Entry
@Component
struct BlankExample {
  build() {
    Row() {
      Text('左侧').fontSize(20)
      Blank()  // 填充中间所有剩余空间
      Text('右侧').fontSize(20)
    }
    .width('100%')
    .padding(10)
    .backgroundColor('#ff386da2')
  }
}

在这里插入图片描述

实际应用示例

登录界面

@Entry
@Component
struct LoginPage {
  @State username: string = ''
  @State password: string = ''
  @State rememberMe: boolean = false

  build() {
    Column({ space: 20 }) {
      Image('logo.png')
        .width(80)
        .height(80)
        .margin({ top: 60, bottom: 20 })
      
      TextInput({ placeholder: '用户名' })
        .width('80%')
        .height(50)
        .onChange((value: string) => {
          this.username = value
        })
      
      TextInput({ placeholder: '密码' })
        .width('80%')
        .height(50)
        .type(InputType.Password)
        .showPasswordIcon(true)
        .onChange((value: string) => {
          this.password = value
        })
      
      Button('登录')
        .width('80%')
        .height(50)
        .backgroundColor('#0099FF')
        .fontColor(Color.White)
        .borderRadius(8)
        .onClick(() => {
          // 处理登录逻辑
          console.info(`登录: 用户名=${this.username}, 密码=${this.password}`)
        })
      
      Row() {
        Checkbox()
          .select(this.rememberMe)
          .onChange((value: boolean) => {
            this.rememberMe = value
          })
        Text('记住我')
          .fontSize(14)
          .fontColor('#36D')
          .margin({ left: 5 })
      }
      .width('80%')
      .justifyContent(FlexAlign.Start)
    }
    .width('100%')
    .height('100%')
    .backgroundColor('#F1F3F5')
    .justifyContent(FlexAlign.Start)
    .alignItems(HorizontalAlign.Center)
  }
}

在这里插入图片描述

列表项

@Entry
@Component
struct ListItemExample {
  build() {
    Column() {
      // 列表标题
      Text('我的设备列表')
        .fontSize(22)
        .fontWeight(FontWeight.Bold)
        .width('100%')
        .padding(16)

      // 列表项1
      Row() {
        Image('device1.png')
          .width(50)
          .height(50)
          .borderRadius(25)
        
        Column() {
          Text('智能手表')
            .fontSize(18)
            .fontWeight(FontWeight.Medium)
          Text('已连接')
            .fontSize(14)
            .fontColor('#66A')
        }
        .layoutWeight(1)
        .alignItems(HorizontalAlign.Start)
        .margin({ left: 12 })
        
        Text('设置')
          .fontColor('#0099FF')
      }
      .width('90%')
      .padding(16)
      .backgroundColor(Color.White)
      .borderRadius(8)
      .margin({ top: 8 })

      // 列表项2
      Row() {
        Image('device2.png')
          .width(50)
          .height(50)
          .borderRadius(25)
        
        Column() {
          Text('智能音箱')
            .fontSize(18)
            .fontWeight(FontWeight.Medium)
          Text('离线')
            .fontSize(14)
            .fontColor('#888')
        }
        .layoutWeight(1)
        .alignItems(HorizontalAlign.Start)
        .margin({ left: 12 })
        
        Text('设置')
          .fontColor('#0099FF')
      }
      .width('90%')
      .padding(16)
      .backgroundColor(Color.White)
      .borderRadius(8)
      .margin({ top: 8 })
    }
    .width('100%')
    .height('100%')
    .backgroundColor('#F5F5F5')
    .alignItems(HorizontalAlign.Center)
  }
}

在这里插入图片描述

性能优化

在开发过程中,合理使用Column和Row可以优化应用性能:

  1. 避免嵌套过深:减少布局层级可以提高渲染效率
  2. 使用懒加载:对于大列表,使用LazyForEach加载数据
  3. 合理设置尺寸:显式设置组件尺寸可以减少重新计算布局的次数
  4. 替代Flex:在一些场景下,使用Column和Row替代Flex可以获得更好的性能

总结

今日学习之旅已圆满收笔,愿每位君子都满载而归,心有所悟!🤩

若你对这探索之旅情有独钟,何不紧随此专栏的步伐?新知如潮,连绵不绝,将与你共绘思维的绚烂篇章,舞动智慧的火花!😎

轻轻一点下方名片,加入我们的粉丝大家庭,让我们在知识的浩瀚海洋中再次相逢,携手见证智慧之花的绚丽绽放,共享求知的喜悦与盛宴!👍
在这里插入图片描述

评论 42
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

颜颜yan_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值