HarmonyOS实战开发:线性布局(Row/Column)(构建布局)

线性布局(LinearLayout)是开发中最常用的布局,通过线性容器RowColumn构建。线性布局是其他布局的基础,其子元素在线性方向上(水平方向和垂直方向)依次排列。线性布局的排列方向由所选容器组件决定,Column容器内子元素按照垂直方向排列,Row容器内子元素按照水平方向排列。根据不同的排列方向,开发者可选择使用Row或Column容器创建线性布局。

图1 Column容器内子元素排列示意图  

arrangement-child-elements-column

图2 Row容器内子元素排列示意图  

arrangement-child-elements-row

基本概念

  • 布局容器:具有布局能力的容器组件,可以承载其他元素作为其子元素,布局容器会对其子元素进行尺寸计算和布局排列。

  • 布局子元素:布局容器内部的元素。

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

  • 交叉轴:垂直于主轴方向的轴线。Row容器交叉轴为垂直方向,Column容器交叉轴为水平方向。

  • 间距:布局子元素的间距。

布局子元素在排列方向上的间距

在布局容器内,可以通过space属性设置排列方向上子元素的间距,使各子元素在排列方向上有等间距效果。

Column容器内排列方向上的间距

图3 Column容器内排列方向的间距图  

arrangement-direction-column

Column({ space: 20 }) {
  Text('space: 20').fontSize(15).fontColor(Color.Gray).width('90%')
  Row().width('90%').height(50).backgroundColor(0xF5DEB3)
  Row().width('90%').height(50).backgroundColor(0xD2B48C)
  Row().width('90%').height(50).backgroundColor(0xF5DEB3)
}.width('100%')

arrangement-direction-column-sample

Row容器内排列方向上的间距

图4 Row容器内排列方向的间距图  

arrangement-direction-row

Row({ space: 35 }) {
  Text('space: 35').fontSize(15).fontColor(Color.Gray)
  Row().width('10%').height(150).backgroundColor(0xF5DEB3)
  Row().width('10%').height(150).backgroundColor(0xD2B48C)
  Row().width('10%').height(150).backgroundColor(0xF5DEB3)
}.width('90%')

zh-cn_image_0000001562700509

布局子元素在交叉轴上的对齐方式

在布局容器内,可以通过alignItems属性设置子元素在交叉轴(排列方向的垂直方向)上的对齐方式。且在各类尺寸屏幕中,表现一致。其中,交叉轴为垂直方向时,取值为VerticalAlign类型,水平方向取值为HorizontalAlign

alignSelf属性用于控制单个子元素在容器交叉轴上的对齐方式,其优先级高于alignItems属性,如果设置了alignSelf属性,则在单个子元素上会覆盖alignItems属性。

Column容器内子元素在水平方向上的排列

图5 Column容器内子元素在水平方向上的排列图  

horizontal-arrangement-child-column

  • HorizontalAlign.Start:子元素在水平方向左对齐。

    Column({}) {
      Column() {
      }.width('80%').height(50).backgroundColor(0xF5DEB3)
    
      Column() {
      }.width('80%').height(50).backgroundColor(0xD2B48C)
    
      Column() {
      }.width('80%').height(50).backgroundColor(0xF5DEB3)
    }.width('100%').alignItems(HorizontalAlign.Start).backgroundColor('rgb(242,242,242)')

    zh-cn_image_0000001511580964

  • HorizontalAlign.Center:子元素在水平方向居中对齐。

    Column({}) {
      Column() {
      }.width('80%').height(50).backgroundColor(0xF5DEB3)
    
      Column() {
      }.width('80%').height(50).backgroundColor(0xD2B48C)
    
      Column() {
      }.width('80%').height(50).backgroundColor(0xF5DEB3)
    }.width('100%').alignItems(HorizontalAlign.Center).backgroundColor('rgb(242,242,242)')

    zh-cn_image_0000001562820897

  • HorizontalAlign.End:子元素在水平方向右对齐。

    Column({}) {
      Column() {
      }.width('80%').height(50).backgroundColor(0xF5DEB3)
    
      Column() {
      }.width('80%').height(50).backgroundColor(0xD2B48C)
    
      Column() {
      }.width('80%').height(50).backgroundColor(0xF5DEB3)
    }.width('100%').alignItems(HorizontalAlign.End).backgroundColor('rgb(242,242,242)')

    zh-cn_image_0000001511421348

Row容器内子元素在垂直方向上的排列

图6 Row容器内子元素在垂直方向上的排列图  

horizontal-arrangement-child-row

  • VerticalAlign.Top:子元素在垂直方向顶部对齐。

    Row({}) {
      Column() {
      }.width('20%').height(30).backgroundColor(0xF5DEB3)
    
      Column() {
      }.width('20%').height(30).backgroundColor(0xD2B48C)
    
      Column() {
      }.width('20%').height(30).backgroundColor(0xF5DEB3)
    }.width('100%').height(200).alignItems(VerticalAlign.Top).backgroundColor('rgb(242,242,242)')

    zh-cn_image_0000001563060765

  • VerticalAlign.Center:子元素在垂直方向居中对齐。

    Row({}) {
      Column() {
      }.width('20%').height(30).backgroundColor(0xF5DEB3)
    
      Column() {
      }.width('20%').height(30).backgroundColor(0xD2B48C)
    
      Column() {
      }.width('20%').height(30).backgroundColor(0xF5DEB3)
    }.width('100%').height(200).alignItems(VerticalAlign.Center).backgroundColor('rgb(242,242,242)')

    zh-cn_image_0000001562700505

  • VerticalAlign.Bottom:子元素在垂直方向底部对齐。

    Row({}) {
      Column() {
      }.width('20%').height(30).backgroundColor(0xF5DEB3)
    
      Column() {
      }.width('20%').height(30).backgroundColor(0xD2B48C)
    
      Column() {
      }.width('20%').height(30).backgroundColor(0xF5DEB3)
    }.width('100%').height(200).alignItems(VerticalAlign.Bottom).backgroundColor('rgb(242,242,242)')

    zh-cn_image_0000001563060781

布局子元素在主轴上的排列方式

在布局容器内,可以通过justifyContent属性设置子元素在容器主轴上的排列方式。可以从主轴起始位置开始排布,也可以从主轴结束位置开始排布,或者均匀分割主轴的空间。

Column容器内子元素在垂直方向上的排列

图7 Column容器内子元素在垂直方向上的排列图 

vertial-arrangement-child-column

  • justifyContent(FlexAlign.Start):元素在垂直方向方向首端对齐,第一个元素与行首对齐,同时后续的元素与前一个对齐。

    Column({}) {
      Column() {
      }.width('80%').height(50).backgroundColor(0xF5DEB3)
    
      Column() {
      }.width('80%').height(50).backgroundColor(0xD2B48C)
    
      Column() {
      }.width('80%').height(50).backgroundColor(0xF5DEB3)
    }.width('100%').height(300).backgroundColor('rgb(242,242,242)').justifyContent(FlexAlign.Start)

    zh-cn_image_0000001562700501

  • justifyContent(FlexAlign.Center):元素在垂直方向方向中心对齐,第一个元素与行首的距离与最后一个元素与行尾距离相同。

    Column({}) {
      Column() {
      }.width('80%').height(50).backgroundColor(0xF5DEB3)
    
      Column() {
      }.width('80%').height(50).backgroundColor(0xD2B48C)
    
      Column() {
      }.width('80%').height(50).backgroundColor(0xF5DEB3)
    }.width('100%').height(300).backgroundColor('rgb(242,242,242)').justifyContent(FlexAlign.Center)

    zh-cn_image_0000001562700517

  • justifyContent(FlexAlign.End):元素在垂直方向方向尾部对齐,最后一个元素与行尾对齐,其他元素与后一个对齐。

    Column({}) {
      Column() {
      }.width('80%').height(50).backgroundColor(0xF5DEB3)
    
      Column() {
      }.width('80%').height(50).backgroundColor(0xD2B48C)
    
      Column() {
      }.width('80%').height(50).backgroundColor(0xF5DEB3)
    }.width('100%').height(300).backgroundColor('rgb(242,242,242)').justifyContent(FlexAlign.End)

    zh-cn_image_0000001562940585

  • justifyContent(FlexAlign.SpaceBetween):垂直方向均匀分配元素,相邻元素之间距离相同。第一个元素与行首对齐,最后一个元素与行尾对齐。

    Column({}) {
      Column() {
      }.width('80%').height(50).backgroundColor(0xF5DEB3)
    
      Column() {
      }.width('80%').height(50).backgroundColor(0xD2B48C)
    
      Column() {
      }.width('80%').height(50).backgroundColor(0xF5DEB3)
    }.width('100%').height(300).backgroundColor('rgb(242,242,242)').justifyContent(FlexAlign.SpaceBetween)

    zh-cn_image_0000001511900532

  • justifyContent(FlexAlign.SpaceAround):垂直方向均匀分配元素,相邻元素之间距离相同。第一个元素到行首的距离和最后一个元素到行尾的距离是相邻元素之间距离的一半。

    Column({}) {
      Column() {
      }.width('80%').height(50).backgroundColor(0xF5DEB3)
    
      Column() {
      }.width('80%').height(50).backgroundColor(0xD2B48C)
    
      Column() {
      }.width('80%').height(50).backgroundColor(0xF5DEB3)
    }.width('100%').height(300).backgroundColor('rgb(242,242,242)').justifyContent(FlexAlign.SpaceAround)

    zh-cn_image_0000001562700525

  • justifyContent(FlexAlign.SpaceEvenly):垂直方向均匀分配元素,相邻元素之间的距离、第一个元素与行首的间距、最后一个元素到行尾的间距都完全一样。

    Column({}) {
      Column() {
      }.width('80%').height(50).backgroundColor(0xF5DEB3)
    
      Column() {
      }.width('80%').height(50).backgroundColor(0xD2B48C)
    
      Column() {
      }.width('80%').height(50).backgroundColor(0xF5DEB3)
    }.width('100%').height(300).backgroundColor('rgb(242,242,242)').justifyContent(FlexAlign.SpaceEvenly)

    zh-cn_image_0000001563060785

Row容器内子元素在水平方向上的排列

图8 Row容器内子元素在水平方向上的排列图  

vertial-arrangement-child-row

  • justifyContent(FlexAlign.Start):元素在水平方向首端对齐,第一个元素与行首对齐,同时后续的元素与前一个对齐。

    Row({}) {
      Column() {
      }.width('20%').height(30).backgroundColor(0xF5DEB3)
    
      Column() {
      }.width('20%').height(30).backgroundColor(0xD2B48C)
    
      Column() {
      }.width('20%').height(30).backgroundColor(0xF5DEB3)
    }.width('100%').height(200).backgroundColor('rgb(242,242,242)').justifyContent(FlexAlign.Start)

    zh-cn_image_0000001511421356

  • justifyContent(FlexAlign.Center):元素在水平方向中心对齐,第一个元素与行首的距离与最后一个元素与行尾距离相同。

    Row({}) {
      Column() {
      }.width('20%').height(30).backgroundColor(0xF5DEB3)
    
      Column() {
      }.width('20%').height(30).backgroundColor(0xD2B48C)
    
      Column() {
      }.width('20%').height(30).backgroundColor(0xF5DEB3)
    }.width('100%').height(200).backgroundColor('rgb(242,242,242)').justifyContent(FlexAlign.Center)

    zh-cn_image_0000001511900516

  • justifyContent(FlexAlign.End):元素在水平方向尾部对齐,最后一个元素与行尾对齐,其他元素与后一个对齐。

    Row({}) {
      Column() {
      }.width('20%').height(30).backgroundColor(0xF5DEB3)
    
      Column() {
      }.width('20%').height(30).backgroundColor(0xD2B48C)
    
      Column() {
      }.width('20%').height(30).backgroundColor(0xF5DEB3)
    }.width('100%').height(200).backgroundColor('rgb(242,242,242)').justifyContent(FlexAlign.End)

    zh-cn_image_0000001562940601

  • justifyContent(FlexAlign.SpaceBetween):水平方向均匀分配元素,相邻元素之间距离相同。第一个元素与行首对齐,最后一个元素与行尾对齐。

    Row({}) {
      Column() {
      }.width('20%').height(30).backgroundColor(0xF5DEB3)
    
      Column() {
      }.width('20%').height(30).backgroundColor(0xD2B48C)
    
      Column() {
      }.width('20%').height(30).backgroundColor(0xF5DEB3)
    }.width('100%').height(200).backgroundColor('rgb(242,242,242)').justifyContent(FlexAlign.SpaceBetween)

    zh-cn_image_0000001562700521

  • justifyContent(FlexAlign.SpaceAround):水平方向均匀分配元素,相邻元素之间距离相同。第一个元素到行首的距离和最后一个元素到行尾的距离是相邻元素之间距离的一半。

    Row({}) {
      Column() {
      }.width('20%').height(30).backgroundColor(0xF5DEB3)
    
      Column() {
      }.width('20%').height(30).backgroundColor(0xD2B48C)
    
      Column() {
      }.width('20%').height(30).backgroundColor(0xF5DEB3)
    }.width('100%').height(200).backgroundColor('rgb(242,242,242)').justifyContent(FlexAlign.SpaceAround)

    zh-cn_image_0000001562820893

  • justifyContent(FlexAlign.SpaceEvenly):水平方向均匀分配元素,相邻元素之间的距离、第一个元素与行首的间距、最后一个元素到行尾的间距都完全一样。

    Row({}) {
      Column() {
      }.width('20%').height(30).backgroundColor(0xF5DEB3)
    
      Column() {
      }.width('20%').height(30).backgroundColor(0xD2B48C)
    
      Column() {
      }.width('20%').height(30).backgroundColor(0xF5DEB3)
    }.width('100%').height(200).backgroundColor('rgb(242,242,242)').justifyContent(FlexAlign.SpaceEvenly)

    zh-cn_image_0000001511421352

自适应拉伸

在线性布局下,常用空白填充组件Blank,在容器主轴方向自动填充空白空间,达到自适应拉伸效果。Row和Column作为容器,只需要添加宽高为百分比,当屏幕宽高发生变化时,会产生自适应效果。

@Entry
@Component
struct BlankExample {
  build() {
    Column() {
      Row() {
        Text('Bluetooth').fontSize(18)
        Blank()
        Toggle({ type: ToggleType.Switch, isOn: true })
      }.backgroundColor(0xFFFFFF).borderRadius(15).padding({ left: 12 }).width('100%')
    }.backgroundColor(0xEFEFEF).padding(20).width('100%')
  }
}

图9 竖屏  

zh-cn_image_0000001562820881

图10 横屏  

zh-cn_image_0000001511421332

自适应缩放

自适应缩放是指子元素随容器尺寸的变化而按照预设的比例自动调整尺寸,适应各种不同大小的设备。在线性布局中,可以使用以下两种方法实现自适应缩放。

  • 父容器尺寸确定时,使用layoutWeight属性设置子元素和兄弟元素在主轴上的权重,忽略元素本身尺寸设置,使它们在任意尺寸的设备下自适应占满剩余空间。

    @Entry
    @Component
    struct layoutWeightExample {
      build() {
        Column() {
          Text('1:2:3').width('100%')
          Row() {
            Column() {
              Text('layoutWeight(1)')
                .textAlign(TextAlign.Center)
            }.layoutWeight(1).backgroundColor(0xF5DEB3).height('100%')
    
            Column() {
              Text('layoutWeight(2)')
                .textAlign(TextAlign.Center)
            }.layoutWeight(2).backgroundColor(0xD2B48C).height('100%')
    
            Column() {
              Text('layoutWeight(3)')
                .textAlign(TextAlign.Center)
            }.layoutWeight(3).backgroundColor(0xF5DEB3).height('100%')
    
          }.backgroundColor(0xffd306).height('30%')
    
          Text('2:5:3').width('100%')
          Row() {
            Column() {
              Text('layoutWeight(2)')
                .textAlign(TextAlign.Center)
            }.layoutWeight(2).backgroundColor(0xF5DEB3).height('100%')
    
            Column() {
              Text('layoutWeight(5)')
                .textAlign(TextAlign.Center)
            }.layoutWeight(5).backgroundColor(0xD2B48C).height('100%')
    
            Column() {
              Text('layoutWeight(3)')
                .textAlign(TextAlign.Center)
            }.layoutWeight(3).backgroundColor(0xF5DEB3).height('100%')
          }.backgroundColor(0xffd306).height('30%')
        }
      }
    }

    图11 横屏  

    zh-cn_image_0000001511421336

    图12 竖屏  

    zh-cn_image_0000001511580968

  • 父容器尺寸确定时,使用百分比设置子元素和兄弟元素的宽度,使他们在任意尺寸的设备下保持固定的自适应占比。

    @Entry
    @Component
    struct WidthExample {
      build() {
        Column() {
          Row() {
            Column() {
              Text('left width 20%')
                .textAlign(TextAlign.Center)
            }.width('20%').backgroundColor(0xF5DEB3).height('100%')
    
            Column() {
              Text('center width 50%')
                .textAlign(TextAlign.Center)
            }.width('50%').backgroundColor(0xD2B48C).height('100%')
    
            Column() {
              Text('right width 30%')
                .textAlign(TextAlign.Center)
            }.width('30%').backgroundColor(0xF5DEB3).height('100%')
          }.backgroundColor(0xffd306).height('30%')
        }
      }
    }

    图13 横屏  

    zh-cn_image_0000001563060777

    图14 竖屏  

    zh-cn_image_0000001511740564

自适应延伸

自适应延伸是指在不同尺寸设备下,当页面的内容超出屏幕大小而无法完全显示时,可以通过滚动条进行拖动展示。这种方法适用于线性布局中内容无法一屏展示的场景。通常有以下两种实现方式。

  • 在List中添加滚动条:当List子项过多一屏放不下时,可以将每一项子元素放置在不同的组件中,通过滚动条进行拖动展示。可以通过scrollBar属性设置滚动条的常驻状态,edgeEffect属性设置拖动到内容最末端的回弹效果。

  • 使用Scroll组件:在线性布局中,开发者可以进行垂直方向或者水平方向的布局。当一屏无法完全显示时,可以在Column或Row组件的外层包裹一个可滚动的容器组件Scroll来实现可滑动的线性布局。 垂直方向布局中使用Scroll组件:

    @Entry
    @Component
    struct ScrollExample {
      scroller: Scroller = new Scroller();
      private arr: number[] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
    
      build() {
        Scroll(this.scroller) {
          Column() {
            ForEach(this.arr, (item?:number|undefined) => {
              if(item){
                Text(item.toString())
                .width('90%')
                .height(150)
                .backgroundColor(0xFFFFFF)
                .borderRadius(15)
                .fontSize(16)
                .textAlign(TextAlign.Center)
                .margin({ top: 10 })
              }
            }, (item:number) => item.toString())
          }.width('100%')
        }
        .backgroundColor(0xDCDCDC)
        .scrollable(ScrollDirection.Vertical) // 滚动方向为垂直方向
        .scrollBar(BarState.On) // 滚动条常驻显示
        .scrollBarColor(Color.Gray) // 滚动条颜色
        .scrollBarWidth(10) // 滚动条宽度
        .edgeEffect(EdgeEffect.Spring) // 滚动到边沿后回弹
      }
    }

    zh-cn_image_0000001511900524

    水平方向布局中使用Scroll组件:

@Entry
@Component
struct ScrollExample {
  scroller: Scroller = new Scroller();
  private arr: number[] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];

  build() {
    Scroll(this.scroller) {
      Row() {
        ForEach(this.arr, (item?:number|undefined) => {
          if(item){
            Text(item.toString())
            .height('90%')
            .width(150)
            .backgroundColor(0xFFFFFF)
            .borderRadius(15)
            .fontSize(16)
            .textAlign(TextAlign.Center)
            .margin({ left: 10 })
          }
        })
      }.height('100%')
    }
    .backgroundColor(0xDCDCDC)
    .scrollable(ScrollDirection.Horizontal) // 滚动方向为水平方向
    .scrollBar(BarState.On) // 滚动条常驻显示
    .scrollBarColor(Color.Gray) // 滚动条颜色
    .scrollBarWidth(10) // 滚动条宽度
    .edgeEffect(EdgeEffect.Spring) // 滚动到边沿后回弹
  }
}

zh-cn_image_0000001562940609

最后

有很多小伙伴不知道学习哪些鸿蒙开发技术?不知道需要重点掌握哪些鸿蒙应用开发知识点?而且学习时频繁踩坑,最终浪费大量时间。所以有一份实用的鸿蒙(HarmonyOS NEXT)资料用来跟着学习是非常有必要的。 

这份鸿蒙(HarmonyOS NEXT)资料包含了鸿蒙开发必掌握的核心知识要点,内容包含了ArkTS、ArkUI开发组件、Stage模型、多端部署、分布式应用开发、音频、视频、WebGL、OpenHarmony多媒体技术、Napi组件、OpenHarmony内核、Harmony南向开发、鸿蒙项目实战等等)鸿蒙(HarmonyOS NEXT)技术知识点。

希望这一份鸿蒙学习资料能够给大家带来帮助,有需要的小伙伴自行领取,限时开源,先到先得~无套路领取!!

获取这份完整版高清学习路线,请点击→纯血版全套鸿蒙HarmonyOS学习资料

鸿蒙(HarmonyOS NEXT)最新学习路线

  •  HarmonOS基础技能

  • HarmonOS就业必备技能 
  •  HarmonOS多媒体技术

  • 鸿蒙NaPi组件进阶

  • HarmonOS高级技能

  • 初识HarmonOS内核 
  • 实战就业级设备开发

有了路线图,怎么能没有学习资料呢,小编也准备了一份联合鸿蒙官方发布笔记整理收纳的一套系统性的鸿蒙(OpenHarmony )学习手册(共计1236页)鸿蒙(OpenHarmony )开发入门教学视频,内容包含:ArkTS、ArkUI、Web开发、应用模型、资源分类…等知识点。

获取以上完整版高清学习路线,请点击→纯血版全套鸿蒙HarmonyOS学习资料

《鸿蒙 (OpenHarmony)开发入门教学视频》

《鸿蒙生态应用开发V2.0白皮书》

图片

《鸿蒙 (OpenHarmony)开发基础到实战手册》

OpenHarmony北向、南向开发环境搭建

图片

 《鸿蒙开发基础》

  • ArkTS语言
  • 安装DevEco Studio
  • 运用你的第一个ArkTS应用
  • ArkUI声明式UI开发
  • .……

图片

 《鸿蒙开发进阶》

  • Stage模型入门
  • 网络管理
  • 数据管理
  • 电话服务
  • 分布式应用开发
  • 通知与窗口管理
  • 多媒体技术
  • 安全技能
  • 任务管理
  • WebGL
  • 国际化开发
  • 应用测试
  • DFX面向未来设计
  • 鸿蒙系统移植和裁剪定制
  • ……

图片

《鸿蒙进阶实战》

  • ArkTS实践
  • UIAbility应用
  • 网络案例
  • ……

图片

 获取以上完整鸿蒙HarmonyOS学习资料,请点击→纯血版全套鸿蒙HarmonyOS学习资料

总结

总的来说,华为鸿蒙不再兼容安卓,对中年程序员来说是一个挑战,也是一个机会。只有积极应对变化,不断学习和提升自己,他们才能在这个变革的时代中立于不败之地。

  • 20
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值