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

一、布局子元素在主轴方向上的间距

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

  1. //纵向布局
  2. Column({ space: 20 }) {
  3. Text('space: 20').fontSize(15).fontColor(Color.Gray).width('90%')
  4. Row().width('90%').height(50).backgroundColor(0xF5DEB3)
  5. Row().width('90%').height(50).backgroundColor(0xD2B48C)
  6. Row().width('90%').height(50).backgroundColor(0xF5DEB3)
  7. }.width('100%')

纵向布局

  1. //横向布局
  2. Row({ space: 35 }) {
  3. Text('space: 35').fontSize(15).fontColor(Color.Gray)
  4. Row().width('10%').height(150).backgroundColor(0xF5DEB3)
  5. Row().width('10%').height(150).backgroundColor(0xD2B48C)
  6. Row().width('10%').height(150).backgroundColor(0xF5DEB3)
  7. }.width('90%')

横向布局

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

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

  1. @Entry
  2. @Component
  3. struct LayoutTest{
  4. build() {
  5. Column({space:20}){
  6. Item()
  7. Item()
  8. Item()
  9. }
  10. .size({width:'100%',height:'100%'})
  11. .alignItems(HorizontalAlign.End) //设置交叉轴方向的对齐方式,Column的交叉轴为水平方向
  12. }
  13. }
  14. @Component
  15. struct Item{
  16. build() {
  17. Text('我是文本')
  18. .size({width:150,height:30})
  19. .backgroundColor(Color.Pink)
  20. .fontColor(Color.White)
  21. .textAlign(TextAlign.Center)
  22. }
  23. }

Column交叉轴对齐方式

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

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

  1. @Entry
  2. @Component
  3. struct LayoutTest{
  4. build() {
  5. Column({space:20}){
  6. Item()
  7. Item()
  8. Item()
  9. }
  10. .size({width:'100%',height:'100%'})
  11. .alignItems(HorizontalAlign.Center)
  12. .justifyContent(FlexAlign.SpaceAround) //设置在主轴方向的对齐
  13. }
  14. }

主轴方向的对齐

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

主轴方向的对齐

四、自适应拉伸

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

五、自适应缩放

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

  • 父容器尺寸确定时,使用layoutWeight属性设置子组件和兄弟元素在主轴上的权重,忽略元素本身尺寸设置,使它们在任意尺寸的设备下自适应占满剩余空间。
  1. @Entry
  2. @Component
  3. struct LayoutTest{
  4. build() {
  5. Column() {
  6. Text('1:2:3').width('100%')
  7. Row() {
  8. Column() {
  9. Text('layoutWeight(1)')
  10. .textAlign(TextAlign.Center)
  11. }.layoutWeight(1).backgroundColor(0xF5DEB3).height('100%')
  12. Column() {
  13. Text('layoutWeight(2)')
  14. .textAlign(TextAlign.Center)
  15. }.layoutWeight(2) //设置占比为2
  16. .backgroundColor(0xD2B48C).height('100%')
  17. Column() {
  18. Text('layoutWeight(3)')
  19. .textAlign(TextAlign.Center)
  20. }.layoutWeight(3).backgroundColor(0xF5DEB3).height('100%')
  21. }.backgroundColor(0xffd306).height('30%')
  22. Text('2:5:3').width('100%')
  23. Row() {
  24. Column() {
  25. Text('layoutWeight(2)')
  26. .textAlign(TextAlign.Center)
  27. }.layoutWeight(2).backgroundColor(0xF5DEB3).height('100%')
  28. Column() {
  29. Text('layoutWeight(5)')
  30. .textAlign(TextAlign.Center)
  31. }.layoutWeight(5).backgroundColor(0xD2B48C).height('100%')
  32. Column() {
  33. Text('layoutWeight(3)')
  34. .textAlign(TextAlign.Center)
  35. }.layoutWeight(3).backgroundColor(0xF5DEB3).height('100%')
  36. }.backgroundColor(0xffd306).height('30%')
  37. }
  38. }
  39. }

layoutWeight

  • 父容器尺寸确定时,使用百分比设置子组件和兄弟元素的宽度,使他们在任意尺寸的设备下保持固定的自适应占比。本质上和第一种方式一样。

特别注意:使用layoutWeight属性自适应占满的是剩余空间。在android中也有这个属性,并且效果一样。

六、自适应延伸(滚动条)

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

  • 在List中添加滚动条:当List子项过多一屏放不下时,可以将每一项子元素放置在不同的组件中,通过滚动条进行拖动展示。可以通过scrollBar属性设置滚动条的常驻状态,edgeEffect属性设置拖动到内容最末端的回弹效果。
  • 使用Scroll组件:在线性布局中,开发者可以进行垂直方向或者水平方向的布局。当一屏无法完全显示时,可以在Column或Row组件的外层包裹一个可滚动的容器组件Scroll来实现可滑动的线性布局。 垂直方向布局中使用Scroll组件:
  1. @Entry
  2. @Component
  3. struct LayoutTest{
  4. scroller: Scroller = new Scroller();
  5. private arr: number[] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
  6. build() {
  7. Scroll(this.scroller) {
  8. Column() {
  9. ForEach(this.arr, (item:number) => {
  10. Text(item.toString())
  11. .width('90%')
  12. .height(150)
  13. .backgroundColor(0xFFFFFF)
  14. .borderRadius(15)
  15. .fontSize(16)
  16. .textAlign(TextAlign.Center)
  17. .margin({ top: 10 })
  18. })
  19. }.width('100%')
  20. }
  21. .backgroundColor(0xDCDCDC)
  22. .scrollable(ScrollDirection.Vertical) // 滚动方向为垂直方向
  23. .scrollBar(BarState.On) // 滚动条常驻显示
  24. .scrollBarColor(Color.Orange) // 滚动条颜色
  25. .scrollBarWidth(10) // 滚动条宽度
  26. .edgeEffect(EdgeEffect.Spring) // 滚动到边沿后回弹
  27. }
  28. }

滚动查看