HarmonyOS应用基础--布局高级

目录

 

四. 布局高级

1. 线性布局

1.1. 间距

1.1.1. Row 

1.1.2. Column 

1.2. 布局主方向对齐方式

 1.3. 案例-得物-产品卡片

 1.4. 交叉轴对齐方式

 1.5. 单个子元素交叉轴对齐方式

 1.6. 自适应缩放

 1.7. 案例-用户关注

1.8. 线性布局-Column

1.9. 案例-头条新闻

 2. 弹性布局(Flex)

2.1. 换行

 2.2. 案例-阶段菜单

3. 案例-微店商品


四. 布局高级

今日核心:

  1. 线性布局
  2. Flex 布局

1. 线性布局

线性布局(LinearLayout)是开发中最常用的布局,通过线性容器 Row 和 Column 构建。Column容器内子元素按照垂直方向排列,Row容器内子元素按照水平方向排列。根据不同的排列方向,开发者可选择使用Row或Column容器创建线性布局。

1.1. 间距

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

1.1.1. Row 

@Entry
@Component
struct Index {
  build() {
    Row({ space: 20}) {
      Text('子元素1')
        .width(100)
        .height(40)
        .backgroundColor(Color.Pink)
      Text('子元素2')
        .width(100)
        .height(40)
        .backgroundColor(Color.Orange)
      Text('子元素3')
        .width(100)
        .height(40)
        .backgroundColor(Color.Brown)
    }
  }
}
1.1.2. Column 

@Entry
@Component
struct Index {
  build() {
    Column({ space: 20}) {
      Text('子元素1')
        .width(100)
        .height(40)
        .backgroundColor(Color.Pink)
      Text('子元素2')
        .width(100)
        .height(40)
        .backgroundColor(Color.Orange)
      Text('子元素3')
        .width(100)
        .height(40)
        .backgroundColor(Color.Brown)
    }
  }
}

1.2. 布局主方向对齐方式

属性:justifyContent()

参数:枚举FlexAlign

属性

描述

Start

首端对齐

Center

居中对齐

End

尾部对齐

Spacebetween

两端对齐

子元素之间间距相等

SpaceAround

子元素两侧间距相等

第一个元素到行首的距离和最后一个元素到行尾的距离是相邻元素之间距离的一半

SpaceEvenly

相邻元素之间的距离、第一个元素与行首的间距、最后一个元素到行尾的间距都完全一样

 

@Entry
@Component
struct Index {
  build() {
    Row() {
      Text('子元素1')
        .width(80)
        .height(40)
        .backgroundColor(Color.Pink)
      Text('子元素2')
        .width(80)
        .height(40)
        .backgroundColor(Color.Orange)
      Text('子元素3')
        .width(80)
        .height(40)
        .backgroundColor(Color.Brown)
    }
      .width('100%')
      .height(200)
      .backgroundColor('#ccc')
      // 主布局方向的对齐方式
      .justifyContent(FlexAlign.Center)
      // 两端对齐
      .justifyContent(FlexAlign.SpaceBetween)
  }
}

概念:

  1. 布局主方向在线性布局中叫做布局主轴
  2. 另外一条坐标轴叫做交叉轴

 1.3. 案例-得物-产品卡片

@Entry
@Component
struct Index {
  build() {
    Column() {
      // 产品卡片
      Column({space: 10}) {
        // 图片
        Image($r('app.media.nick'))
          .width('100%')
          .aspectRatio(1)
          .borderRadius({topLeft:5, topRight: 5})
        // 标题文字
        Text('今晚吃这个 | 每日艺术分享 No.43')
          .fontSize(14)
          .fontWeight(600)
          .fontColor('#414141')
          .lineHeight(22)
          .padding({left: 10, right: 10})
        // 用户与点赞
        Row() {
          // 用户
          Row({space: 5}){
            Image($r('app.media.user'))
              .width(15)
              .borderRadius(10)
            Text('插画师分享聚集地')
              .fontSize(10)
              .fontColor('#787a7d')
          }
          // 点赞
          Row({ space: 5}){
            Image($r('app.media.ic_like'))
              .width(10)
              .aspectRatio(1)
              .fillColor('#c2c0ca')
            Text('2300')
              .fontSize(10)
              .fontColor('#787a7d')
          }
        }
        .width('100%')
        .padding({left: 10, right: 10})
        .justifyContent(FlexAlign.SpaceBetween)
      }
      .width(200)
      .padding({bottom:10})
      .backgroundColor('#fff')
      .borderRadius(5)
    }
    .width('100%')
    .height('100%')
    .backgroundColor('#f5f4f9')
    .padding(10)
  }
}

 1.4. 交叉轴对齐方式

 以 Row 为例,主轴在水平方向,交叉轴在垂直方向

属性:alignItems()

参数:枚举类型VerticalAlign

注意:布局容器在交叉轴要有足够空间,否则无法生效

@Entry
@Component
struct Index {
  build() {
    Row() {
      Text('子元素1')
        .width(80)
        .height(40)
        .backgroundColor(Color.Pink)
      Text('子元素2')
        .width(80)
        .height(40)
        .backgroundColor(Color.Orange)
      Text('子元素3')
        .width(80)
        .height(40)
        .backgroundColor(Color.Brown)
    }
      .width('100%')
      .height(200)
      .backgroundColor('#ccc')
      // 顶部对齐
      .alignItems(VerticalAlign.Top)
      // 底部对齐
      .alignItems(VerticalAlign.Bottom)
  }
}

 1.5. 单个子元素交叉轴对齐方式

属性:alignSelf()

参数:枚举ItemAlign(Stretch拉伸,交叉轴拉伸效果)

@Entry
@Component
struct Index {
  build() {
    Row() {
      Text('子元素1')
        .width(80)
        .height(40)
        .backgroundColor(Color.Pink)
      Text('子元素2')
        .width(80)
        .height(40)
        .backgroundColor(Color.Orange)
        // 交叉轴方向尺寸拉伸
        .alignSelf(ItemAlign.Stretch)
      Text('子元素3')
        .width(80)
        .height(40)
        .backgroundColor(Color.Brown)
    }
      .width('100%')
      .height(200)
      .backgroundColor('#ccc')
  }
}

 1.6. 自适应缩放

 

父容器尺寸确定时,设置了 layoutWeight 属性的子元素与兄弟元素占主轴尺寸按照权重进行分配。

属性:layoutWeight()

参数:数字

@Entry
@Component
struct Index {
  build() {
    Column() {
      // 主轴方向:水平方向
      Row() {
        Text('左侧')
          .width(60)
          .height(30)
          .backgroundColor('#ccc')
        Text('中间')
          .height(30)
          .backgroundColor(Color.Pink)
          .layoutWeight(1)
        Text('右侧 layoutWeight')
          .height(30)
          .backgroundColor('#fc0')
          .layoutWeight(1)
      }
    }
  }
}

 1.7. 案例-用户关注

@Entry
@Component
struct Index {
  build() {
    Row() {
      Image($r('app.media.user'))
        .width(30)
        .margin({right: 5})
        .borderRadius(15)
      Text('插画设计师')
        .fontSize(13)
        .fontWeight(700)
        .layoutWeight(1)
      Text('关注')
        .width(40)
        .height(25)
        .border({width: 1, color: '#999'})
        .borderRadius(3)
        .fontSize(12)
        .textAlign(TextAlign.Center)
        .fontColor('#999')
    }
      .width('100%')
      .height(40)
      .padding({left: 10, right: 10})
      .margin({top: 20})
  }
}

1.8. 线性布局-Column

  • Column 主轴方向: 垂直方向
  • Column 交叉轴方向:水平方向
@Entry
@Component
struct Index {
  build() {
    Column() {
      Text('1')
        .width(100)
        .height(40)
        .backgroundColor(Color.Pink)
      Text('2')
        .width(100)
        .height(40)
        .backgroundColor(Color.Orange)
        // 单个元素-交叉轴对齐方式
        .alignSelf(ItemAlign.End)
      Text('3')
        .width(100)
        .height(40)
        .backgroundColor(Color.Pink)
    }
      .width('100%')
      .height(300)
      .backgroundColor('#ccc')
      // 主轴对齐方式 -- 与Row写法一致
      .justifyContent(FlexAlign.SpaceBetween)
      // 交叉轴对齐方式(水平方向),默认居中
      .alignItems(HorizontalAlign.Start)
  }
}

1.9. 案例-头条新闻

@Entry
@Component
struct Index {
  build() {
    Column() {
      Row({space: 10}) {
        // 左侧
        Column() {
          Text('第五个国际数学日,全世界和数据一起玩儿')
            .fontSize(14)
            .fontColor('#444')
          Row() {
            Text('中国青年网 昨天')
              .fontSize(12)
              .fontColor('#999')
              .layoutWeight(1)
            Image($r('app.media.ic_close'))
              .width(14)
              .fillColor('#999')
          }
            .width('100%')
            // .justifyContent(FlexAlign.SpaceBetween)
        }
          .height('100%')
          .layoutWeight(1)
          // 水平左对齐 -- 交叉轴
          .alignItems(HorizontalAlign.Start)
          // 垂直两端对齐 -- 主轴
          .justifyContent(FlexAlign.SpaceBetween)
        // 右侧
        Image($r('app.media.math'))
          .width(100)
      }
        .width('100%')
        .height(80)
        // .backgroundColor('#ccc')
        .padding(5)
        .margin({top: 20})
    }
  }
}

 2. 弹性布局(Flex)

2.1. 换行

弹性布局分为单行布局和多行布局。默认情况下,Flex 容器中的子元素都排在一条线(又称“轴线”)上。子元素尺寸总和大于 Flex 容器尺寸时,子元素尺寸会自动挤压。

wrap 属性控制当子元素主轴尺寸之和大于容器主轴尺寸时,Flex 是单行布局还是多行布局。在多行布局时,通过交叉轴方向,确认新行排列方向。

参数:wrap

值:枚举 FlexWrap

@Entry
@Component
struct Index {
  build() {
    Column() {
      Flex({wrap:FlexWrap.Wrap}) {
        Text()
          .width(80)
          .height(40)
          .backgroundColor(Color.Pink)
          .margin(5)
        Text()
          .width(80)
          .height(40)
          .backgroundColor(Color.Orange)
          .margin(5)
        Text()
          .width(80)
          .height(40)
          .backgroundColor(Color.Pink)
          .margin(5)
        Text()
          .width(80)
          .height(40)
          .backgroundColor(Color.Orange)
          .margin(5)
        Text()
          .width(80)
          .height(40)
          .backgroundColor(Color.Pink)
          .margin(5)
        Text()
          .width(80)
          .height(40)
          .backgroundColor(Color.Orange)
          .margin(5)
      }
        .width('100%')
        .height(200)
        .backgroundColor('#ccc')
    }
  }
}

 2.2. 案例-阶段菜单

@Entry
@Component
struct Index {
  build() {
    Column() {
      Text('阶段选择')
        .fontWeight(600)
        .fontSize(24)
        .width('100%')
        .padding(15)
      Flex({ wrap: FlexWrap.Wrap }) {
        Text('ArkUI')
          .padding(10)
          .margin(5)
          .backgroundColor('#f6f7f9')
        Text('ArkTS')
          .padding(10)
          .margin(5)
          .backgroundColor('#f6f7f9')
        Text('界面开发')
          .padding(10)
          .margin(5)
          .backgroundColor('#f6f7f9')
        Text('系统能力')
          .padding(10)
          .margin(5)
          .backgroundColor('#f6f7f9')
        Text('权限控制')
          .padding(10)
          .margin(5)
          .backgroundColor('#f6f7f9')
        Text('元服务')
          .padding(10)
          .margin(5)
          .backgroundColor('#f6f7f9')
      }
    }
    .width('100%')
    .height('100%')
    .padding(10)
  }
}

3. 案例-微店商品

@Entry
@Component
struct Index {
  build() {
    Column() {
      Flex({ wrap: FlexWrap.Wrap }) {
        Column({ space: 8 }) {
          Image($r('app.media.top1'))
            .width('100%')
            .borderRadius({topLeft: 5, topRight: 5})
          Text('[ 程序员必备 ] 最高版本-格子衫')
            .fontSize(12)
            .maxLines(1)
            .textOverflow({overflow: TextOverflow.Ellipsis})
            .padding({left: 10, right: 10})
          Text() {
            Span('¥666 ')
              .fontSize(12)
              .fontColor('#f52555')
            Span('销量666')
              .fontSize(8)
              .fontColor('#999')
          }
            .padding({left: 10, right: 10})
        }
          .width('47%')
          .backgroundColor('#fff')
          .margin({right: 10, bottom: 10})
          .borderRadius(5)
          .alignItems(HorizontalAlign.Start)
          .padding({bottom: 10})
        Column({ space: 8 }) {
          Image($r('app.media.top2'))
            .width('100%')
            .borderRadius({topLeft: 5, topRight: 5})
          Text('[ 程序员必备 ] 最高版本-格子衫')
            .fontSize(12)
            .maxLines(1)
            .textOverflow({overflow: TextOverflow.Ellipsis})
            .padding({left: 10, right: 10})
          Text() {
            Span('¥888 ')
              .fontSize(12)
              .fontColor('#f52555')
            Span('销量888')
              .fontSize(8)
              .fontColor('#999')
          }
          .padding({left: 10, right: 10})
        }
        .width('47%')
        .backgroundColor('#fff')
        .margin({right: 10, bottom: 10})
        .borderRadius(5)
        .alignItems(HorizontalAlign.Start)
        .padding({bottom: 10})
        Column({ space: 8 }) {
          Image($r('app.media.top3'))
            .width('100%')
            .borderRadius({topLeft: 5, topRight: 5})
          Text('[ 程序员必备 ] 最高版本-格子衫')
            .fontSize(12)
            .maxLines(1)
            .textOverflow({overflow: TextOverflow.Ellipsis})
            .padding({left: 10, right: 10})
          Text() {
            Span('¥333 ')
              .fontSize(12)
              .fontColor('#f52555')
            Span('销量666')
              .fontSize(8)
              .fontColor('#999')
          }
          .padding({left: 10, right: 10})
        }
        .width('47%')
        .backgroundColor('#fff')
        .margin({right: 10, bottom: 10})
        .borderRadius(5)
        .alignItems(HorizontalAlign.Start)
        .padding({bottom: 10})
        Column({ space: 8 }) {
          Image($r('app.media.top4'))
            .width('100%')
            .borderRadius({topLeft: 5, topRight: 5})
          Text('[ 程序员必备 ] 最高版本-格子衫')
            .fontSize(12)
            .maxLines(1)
            .textOverflow({overflow: TextOverflow.Ellipsis})
            .padding({left: 10, right: 10})
          Text() {
            Span('¥444 ')
              .fontSize(12)
              .fontColor('#f52555')
            Span('销量666')
              .fontSize(8)
              .fontColor('#999')
          }
          .padding({left: 10, right: 10})
        }
        .width('47%')
        .backgroundColor('#fff')
        .margin({right: 10, bottom: 10})
        .borderRadius(5)
        .alignItems(HorizontalAlign.Start)
        .padding({bottom: 10})
        Column({ space: 8 }) {
          Image($r('app.media.top2'))
            .width('100%')
            .borderRadius({topLeft: 5, topRight: 5})
          Text('[ 程序员必备 ] 最高版本-格子衫')
            .fontSize(12)
            .maxLines(1)
            .textOverflow({overflow: TextOverflow.Ellipsis})
            .padding({left: 10, right: 10})
          Text() {
            Span('¥555 ')
              .fontSize(12)
              .fontColor('#f52555')
            Span('销量666')
              .fontSize(8)
              .fontColor('#999')
          }
          .padding({left: 10, right: 10})
        }
        .width('47%')
        .backgroundColor('#fff')
        .margin({right: 10, bottom: 10})
        .borderRadius(5)
        .alignItems(HorizontalAlign.Start)
        .padding({bottom: 10})
        Column({ space: 8 }) {
          Image($r('app.media.top5'))
            .width('100%')
            .borderRadius({topLeft: 5, topRight: 5})
          Text('[ 程序员必备 ] 最高版本-格子衫')
            .fontSize(12)
            .maxLines(1)
            .textOverflow({overflow: TextOverflow.Ellipsis})
            .padding({left: 10, right: 10})
          Text() {
            Span('¥444 ')
              .fontSize(12)
              .fontColor('#f52555')
            Span('销量444')
              .fontSize(8)
              .fontColor('#999')
          }
          .padding({left: 10, right: 10})
        }
        .width('47%')
        .backgroundColor('#fff')
        .margin({right: 10, bottom: 10})
        .borderRadius(5)
        .alignItems(HorizontalAlign.Start)
        .padding({bottom: 10})
      }
    }
    .width('100%')
    .height('100%')
    .backgroundColor('#f5f6f7')
    .padding(10)
  }
}

  • 16
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值