鸿蒙开发从入门到入土:4-线性布局 Column 和 Row

0 概述

说到线性布局,不知道做过 Android 开发的朋友是不是跟笔者一样,第一反应就是"这不就是 Android 中的 LinearLayout 么"(脑补一个抠鼻表情)

鸿蒙在ArkUI中,将这个 LinearLayout 拆分成了RowColumn,从名字上也能猜出来这俩人中,Row负责横向的线性布局,也就是相当于 LinearLayout 的 orientation="horizontal";Column负责竖向的线性布局,相当于 LinearLayout 的 orientation="vertical"。

1 基本概念

鸿蒙对于线性布局,引入了 主轴、交叉轴的概念

  • 主轴:线性布局容器在布局方向上的轴线,子元素默认沿主轴排列。Row容器主轴为水平 方向,Column容器主轴为垂直方向。
  • 交叉轴:垂直于主轴方向的轴线。Row容器交叉轴为垂直 方向,Column容器交叉轴为水平方向。

简单来说

  • 主轴:与线性容器中子组件的排列方向一致
  • 交叉轴:与线性容器中子组件的排列方向垂直

2 基本用法

其实ColumnRow的用法差不多,区别就是一个竖向、一个横向,所以本文主要以Column的用法为主,Row的用法跟Column类似,可以看下参考资料中的链接,笔者就不再做过多的介绍了。我们先看个Column的效果图

上图是在Column中添加了三个Text组件,当然为了便于区分,给每个Text组件都增加了背景色,后面会详细介绍Text组件,这里就先不赘述了。这个页面的代码如下:

TypeScript 复制代码
@Entry
@Component
struct Index {

  build() {
    Column() {
      Text('我是孙小胖児')
        .width(160)
        .height(30)
        .fontSize(20)
        .textAlign(TextAlign.Center)
        .fontColor(Color.White)
        .backgroundColor(Color.Brown)

      Text('我是孙小胖児')
        .width(160)
        .height(30)
        .fontSize(20)
        .textAlign(TextAlign.Center)
        .fontColor(Color.White)
        .backgroundColor(Color.Gray)

      Text('我是孙小胖児')
        .width(160)
        .height(30)
        .fontSize(20)
        .textAlign(TextAlign.Center)
        .fontColor(Color.White)
        .backgroundColor(Color.Blue)
    }
    .height('100%')
    .width('100%')
    .padding(16)
    .backgroundColor(0xCCCCCC)
  }
}

上图这段代码中可以看到,第31~34行,是针对Column的设置,width、height、padding、backgroundcolor,这四个属性看着是不是很眼熟

width、height,这两个属性,设置组件的宽高,当然了,因为在这段代码中,Column作为根容器,它的宽高肯定是要填满整个屏幕的,因此也就写了100% ,这里需要注意的是,这个100%是以字符串的形式当作参数的,除了100%,还可以写具体的数值,比如100,这个就表示是100vp,这个vp是鸿蒙的单位,类似于Android的dp。
padding如果只写一个数字,那代表左、上、右、下的padding间距都是16vp,当然也有单独控制的写法,如下所示:

TypeScript 复制代码
.padding({
  top: 16,
  left: 32,
  right: 32,
  bottom: 16
})

当然了,marginpadding一样,也有这两种设置方式,只不过控制的间距是不一样的,padding控制的是组件内部的间距,margin控制的是组件与组件之间的间距。

不过,如果Column / Row 他们的子组件的间距是固定的,那么可以用下面这个方式来设置:

TypeScript 复制代码
@Entry
@Component
struct Index {

  build() {
    Column({space: 20}) { // 通过 space,来设置子组件的间距
      Text('我是孙小胖児')
        .width(160)
        .height(30)
        .fontSize(20)
        .textAlign(TextAlign.Center)
        .fontColor(Color.White)
        .backgroundColor(Color.Brown)

      Text('我是孙小胖児')
        .width(160)
        .height(30)
        .fontSize(20)
        .textAlign(TextAlign.Center)
        .fontColor(Color.White)
        .backgroundColor(Color.Gray)

      Text('我是孙小胖児')
        .width(160)
        .height(30)
        .fontSize(20)
        .textAlign(TextAlign.Center)
        .fontColor(Color.White)
        .backgroundColor(Color.Blue)
    }
    .height('100%')
    .width('100%')
    .padding(16)
    .backgroundColor(0xCCCCCC)
  }
}

运行后的效果如下:

3 子组件的对齐方式

ClomunRow这两个线性容器的子组件对齐方式,主要是针对交叉轴说的。对于Column组件来说交叉轴就是水平方向,自然的对于Row组件来说交叉轴就是垂直方向。Column的交叉轴的对齐方式有三种,分别是:Start、Center、End;Row的交叉轴的对齐方式也有三种,分别是:Top、Center、Bottom。属性都是alignItems,只不过参数一个是HorizontalAlign ,一个是VerticalAlign

Column Row

Column的交叉轴对齐的具体效果如下:

  1. HorizontalAlign.Start
  2. HorizontalAlign.Center
  3. HorizontalAlign.End

Row的交叉轴对齐的具体效果如下:

  1. VerticalAlign.Top
  2. VerticalAlign.Center
  3. VerticalAlign.Bottom

4 子组件的摆放方式

子组件的摆放方式,是针对主轴来说的。前面说过主轴就是线性容器中子组件的排列方向,所以Column的主轴就是垂直方向,Row的主轴就是水平方向。二者设置主轴上子组件的摆放方法,也是个通用属性:.justifyContent()

Column Row 从上面个两张图可以看到,不论是Column还是Row,这个justifyContent属性的参数都是一模一样的

按照惯例,我们还是先看看Column主轴上的对齐效果,为了节省篇幅,把这六个对齐方式拼在一起了

Column
Row
从图中可以看出,FlexAlign.StartFlexAlign.CenterFlexAlign.End 这三种对齐方式对于Column来说分别是:居顶、居中、居底摆放;对于Row来说分别是:居左、居中、居右摆放。

FlexAlign.SpaceBetweenFlexAlign.SpaceAroundFlexAlign.SpaceEvenly 这三种摆放方式,是子组件对于主轴上的空间的分配,从图中可以看出,这三种空间的分配,对于子组件来说,所有子组件的间距是相等的,唯一的区别在于头、尾两个子组件与父容器的间距不同,图中箭头所指的线段,具体的区别为:

  • FlexAlign.SpaceBetween:头、尾两个子组件与父容器的间距为0。
  • FlexAlign.SpaceAround:头、尾两个子组件与父容器的间距是子组件之间间距的一半
  • FlexAlign.SpaceEvenly:头、尾两个子组件与父容器的间距与子组件之间的间距相同

5 三种自适应布局

在鸿蒙的官方开发指南中,线性布局这一章节的最后,是三种自适应的布局,分别是:自适应拉伸、自适应缩放、自适应延伸。咱们分别看看这三个都是什么新鲜玩意儿。

5.1 自适应拉伸

自适应拉伸,按照官方文档的说法,就是在主轴方向的子组件之间放一个名为Blank的组件,从名字上也猜出来,这玩意儿就是个空白组件。使用起来也很简单,就直接写个Blank()就完事了(下面这段代码中的第15行)

TypeScript 复制代码
@Entry
@Component
struct Index {

  build() {
    Row() {
      Text('我是孙小胖児')
        .width(80)
        .height(50)
        .fontSize(20)
        .textAlign(TextAlign.Center)
        .fontColor(Color.White)
        .backgroundColor(Color.Brown)

      Blank()

      Text('我是孙小胖児')
        .width(80)
        .height(50)
        .fontSize(20)
        .textAlign(TextAlign.Center)
        .fontColor(Color.White)
        .backgroundColor(Color.Gray)
    }
    .height('100%')
    .width('100%')
  }
}

运行起来一看效果,我人麻了

这玩意儿跟下面这代码有啥区别??

TypeScript 复制代码
Row() {
}
.justifyContent(FlexAlign.SpaceBetween)

实现的效果不都一样,笔者想了几个小时小时没想明白。如果有哪位朋友理解了这个Blank的奥义,还请在评论区赐教(抱拳了.jpg)

5.2 自适应缩放

开始看到这个标题的时候,有点没反应过来,后来看了下具体的代码,发现指的是layoutWeight这个属性,瞬间就明白了,毕竟这个属性在Android中也有,虽然我用的不太多吧😂好了,不废话了,直接上代码

TypeScript 复制代码
@Entry
@Component
struct Index {

  build() {
    Column() {
      Text('我是孙小胖児\n layoutWeight(1)')
        .layoutWeight(1)
        .width('100%')
        .fontSize(20)
        .textAlign(TextAlign.Center)
        .fontColor(Color.White)
        .backgroundColor(Color.Brown)

      Text('我是孙小胖児\n layoutWeight(2)')
        .layoutWeight(2)
        .width('100%')
        .fontSize(20)
        .textAlign(TextAlign.Center)
        .fontColor(Color.White)
        .backgroundColor(Color.Gray)

      Text('我是孙小胖児\n layoutWeight(3)')
        .layoutWeight(3)
        .width('100%')
        .fontSize(20)
        .textAlign(TextAlign.Center)
        .fontColor(Color.White)
        .backgroundColor(Color.Blue)
    }
    .height('100%')
    .width('100%')
  }
}

上面的代码运行后的效果如下:

对于Row这个容器也是一样

TypeScript 复制代码
@Entry
@Component
struct Index {

  build() {
    Row() {
      Text('我是孙小胖児 layoutWeight(1)')
        .layoutWeight(1)
        .height('100%')
        .fontSize(20)
        .textAlign(TextAlign.Center)
        .fontColor(Color.White)
        .backgroundColor(Color.Brown)

      Text('我是孙小胖児 layoutWeight(2)')
        .layoutWeight(2)
        .height('100%')
        .fontSize(20)
        .textAlign(TextAlign.Center)
        .fontColor(Color.White)
        .backgroundColor(Color.Gray)

      Text('我是孙小胖児 layoutWeight(3)')
        .layoutWeight(3)
        .height('100%')
        .fontSize(20)
        .textAlign(TextAlign.Center)
        .fontColor(Color.White)
        .backgroundColor(Color.Blue)
    }
    .height('100%')
    .height('100%')
  }
}

提示一下:在Column中使用 layoutWeight 的时候,子组件不需要设置高度,相应的,在Row中使用 layoutWeight 的时候,子组件不需要设置宽度

除了 layoutWeight 这个属性可以使子组件自适应缩放以外,还可以在设置widthheight这两个属性的时候,直接写百分比。

TypeScript 复制代码
@Entry
@Component
struct Index {

  build() {
    Column() {
      Text('我是孙小胖児 height(\'20%\')')
        .height('20%')
        .width('100%')
        .fontSize(20)
        .textAlign(TextAlign.Center)
        .fontColor(Color.White)
        .backgroundColor(Color.Brown)

      Text('我是孙小胖児 height(\'30%\')')
        .height('30%')
        .width('100%')
        .fontSize(20)
        .textAlign(TextAlign.Center)
        .fontColor(Color.White)
        .backgroundColor(Color.Gray)

      Text('我是孙小胖児 height(\'50%\')')
        .height('50%')
        .width('100%')
        .fontSize(20)
        .textAlign(TextAlign.Center)
        .fontColor(Color.White)
        .backgroundColor(Color.Blue)
    }
    .width('100%')
    .width('100%')
  }
}

上面是在Column中用百分比来设置withheight 的方式实现自适应缩放,Row容器的用法类似,就不再赘述了。

5.3 自适应延伸

这个自适应延伸,实际上就是使用Scroll组件,或者List组件来实现页面的滚动效果,当然了除非是列表页面,否则大部分情况下都是使用Scroll实现页面的滚动效果,后面会单独写Scroll组件,就不再赘述了。

本文正在参加华为鸿蒙有奖征文征文活动

参考资料

  1. 线性布局(Row / Column)
相关推荐
SameX2 小时前
HarmonyOS Next 安全生态构建与展望
前端·harmonyos
SameX2 小时前
HarmonyOS Next 打造智能家居安全系统实战
harmonyos
Random_index9 小时前
#Uniapp篇:支持纯血鸿蒙&发布&适配&UIUI
uni-app·harmonyos
鸿蒙自习室13 小时前
鸿蒙多线程开发——线程间数据通信对象02
ui·harmonyos·鸿蒙
SuperHeroWu715 小时前
【HarmonyOS】鸿蒙应用接入微博分享
华为·harmonyos·鸿蒙·微博·微博分享·微博sdk集成·sdk集成
zhangjr057518 小时前
【HarmonyOS Next】鸿蒙实用装饰器一览(一)
前端·harmonyos·arkts
诗歌难吟4641 天前
初识ArkUI
harmonyos
SameX1 天前
HarmonyOS Next 设备安全特性深度剖析学习
harmonyos
郭梧悠1 天前
HarmonyOS(57) UI性能优化
ui·性能优化·harmonyos
郝晨妤2 天前
鸿蒙原生应用开发元服务 元服务是什么?和App的关系?(保姆级步骤)
android·ios·华为od·华为·华为云·harmonyos·鸿蒙