【HarmonyOS5】Column和Row组件详解

前言
在HarmonyOS的ArkUI框架中,布局是构建应用界面的基础。其中Column和Row是两个最常用的线性布局容器组件,它们帮助开发者以简单灵活的方式组织和排列界面元素。
基本概念
在了解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提供了两种对齐方式的属性:
- justifyContent:控制子组件在主轴方向上的对齐方式
 - 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可以优化应用性能:
- 避免嵌套过深:减少布局层级可以提高渲染效率
 - 使用懒加载:对于大列表,使用
LazyForEach加载数据 - 合理设置尺寸:显式设置组件尺寸可以减少重新计算布局的次数
 - 替代Flex:在一些场景下,使用Column和Row替代Flex可以获得更好的性能
 
总结
今日学习之旅已圆满收笔,愿每位君子都满载而归,心有所悟!🤩
若你对这探索之旅情有独钟,何不紧随此专栏的步伐?新知如潮,连绵不绝,将与你共绘思维的绚烂篇章,舞动智慧的火花!😎
轻轻一点下方名片,加入我们的粉丝大家庭,让我们在知识的浩瀚海洋中再次相逢,携手见证智慧之花的绚丽绽放,共享求知的喜悦与盛宴!👍
- 点赞
 - 收藏
 - 关注作者
 
            
           
评论(0)