鸿蒙开发从入门到入土: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)
相关推荐
SuperHeroWu73 小时前
【HarmonyOS】Beta最新对外版本IDE下载和环境配置
ide·华为·harmonyos
xq9527--5 小时前
鸿蒙next web组件和h5 交互实战来了
华为·harmonyos
PlumCarefree14 小时前
基于鸿蒙API10的RTSP播放器(八:音量和亮度调节功能的整合)
华为·ffmpeg·音视频·harmonyos
Android技术栈16 小时前
鸿蒙开发(NEXT/API 12)【使用fetchsync发送同步网络请求 (C/C++)】 远场通信服务
c语言·网络·c++·信息与通信·harmonyos·鸿蒙系统·openharmony
OH五星上将1 天前
OpenHarmony(鸿蒙南向开发)——标准系统移植指南(一)
harmonyos·移植·openharmony·鸿蒙开发·鸿蒙内核·子系统
OH五星上将1 天前
OpenHarmony(鸿蒙南向开发)——标准系统移植指南(二)Linux内核
linux·驱动开发·嵌入式硬件·移动开发·harmonyos·鸿蒙开发·鸿蒙内核
JohnLiu_2 天前
HarmonyOS Next鸿蒙扫一扫功能实现
华为·harmonyos·鸿蒙·扫一扫
weixin_424343022 天前
2024年8月HarmonyOS鸿蒙应用开发者高级认证全新题库
华为·harmonyos
让开,我要吃人了2 天前
OpenHarmony鸿蒙( Beta5.0)RTSPServer实现播放视频详解
驱动开发·嵌入式硬件·华为·移动开发·harmonyos·鸿蒙·openharmony
OH五星上将2 天前
OpenHarmony(鸿蒙南向开发)——轻量和小型系统三方库移植指南(二)
驱动开发·移动开发·harmonyos·内存管理·openharmony·鸿蒙内核·鸿蒙移植