目录

一、工程结构与代码入口

二、核心布局:容器组件与内容组件

1. 组件分类

2. 常用容器组件

3. 容器组件核心对齐属性

三、组件属性

1. 属性通用规则

2. 通用属性

3. 内容组件专属属性

(1)Text文本组件

(2)Image图片组件

(3)Button按钮组件

四、实战布局:黑马云音乐

1. 实操步骤

2. 完整可运行代码


一、工程结构与代码入口

        界面代码默认写在pages/index/index.ets文件中,核心结构固定如下:

// 1. @Entry:标记当前组件是应用入口(整个App的起始页面)
@Entry
// 2. @Component:标记当前结构体是一个UI组件(可复用)
@Component
// 3. struct:定义组件结构体(组件的核心载体)
struct Index {
  // 4. build()方法:所有界面代码必须写在build()内,是组件的UI渲染入口
  build() {
    // 根容器:每个页面必须有且仅有一个根容器(Column/Row/Stack等)
    Column() {
      // 子组件写在这里
    }
  }
}

二、核心布局:容器组件与内容组件

1. 组件分类

类型

定义

写法规则

核心特点

示例

容器组件

承载其他组件的“框架”

组件名() { 内部子组件 }

可嵌套,控制子组件排列方式

Column、Row、Stack、List

内容组件

展示具体内容的“元素”

组件名(内容/配置)

不可嵌套,仅展示内容

Text、Image、Button、Input

2. 常用容器组件

组件名

排列方式

核心属性

适用场景

Column

垂直排列

justifyContent(垂直对齐)、alignItems(水平对齐)

页面整体布局、列表项、竖向表单

Row

水平排列

同Column

横向导航栏、列表项内布局、按钮组

Stack

层叠排列

alignContent(层叠对齐)

带背景图的文本、悬浮按钮

List

滚动列表

scrollDirection(滚动方向)、scrollBar(滚动条)

长列表、商品列表、歌曲列表

3. 容器组件核心对齐属性

@Entry
@Component
struct AlignDemo {
  build() {
    Column() {
      Text("居中对齐示例")
        .width(100)
        .height(50)
        .backgroundColor(Color.Pink)
    }
    .width('100%')
    .height('100%')
    .justifyContent(FlexAlign.Center) // 垂直居中(FlexAlign类型)
    .alignItems(HorizontalAlign.Center) // 水平居中
    .backgroundColor('#F0F0F0')
  }
}

三、组件属性

1. 属性通用规则

  • 写法:组件名().属性名(属性值),多个属性必须换行,示例:

    Text("Hello World")
      .fontSize(24) // 换行写属性,可读性强
      .fontColor(Color.Black)
      .width('100%')
    • 优先级:组件自身属性 > 父容器继承属性;

    • 单位规则:所有数值型属性(宽高、边距、字体大小)默认单位:

      • VP(虚拟像素):宽高、边距、边框等布局属性,自动适配不同屏幕尺寸;

      • SP(缩放像素):字体大小,自动适配系统字体缩放设置;

    2. 通用属性

    属性名

    作用

    取值示例

    注意点

    width

    宽度

    100、'100%'、'auto'

    'auto'表示自适应内容宽度,优先于固定数值

    height

    高度

    同width

    容器组件默认height为'auto',内容组件默认自适应

    backgroundColor

    背景色

    Color.Red、'#FF0000'、'rgb(255,0,0)'

    16进制色值需写全6位(#RRGGBB)

    padding

    内边距

    15、{left:10, right:10, top:5, bottom:5}

    定向边距可单独设置某一个方向,优先级高于统一值

    margin

    外边距

    同padding

    margin是组件与外部元素的间距,padding是组件内部内容与边框的间距

    border

    边框

    {width:2, color:Color.Black, style:BorderStyle.Solid, radius:8}

    style可选Solid(实线)、Dashed(虚线)、Dotted(点线)

    opacity

    透明度

    0.1~1

    1为不透明,0为完全透明,0.5为半透明(适用于所有组件)

    3. 内容组件专属属性

    (1)Text文本组件
    @Entry
    @Component
    struct TextFullDemo {
      build() {
        Column({ space: 10 }) { // space:子组件之间的间距(Column/Row专属)
          Text("HarmonyOS界面开发")
            .fontSize(24) // 字体大小(SP)
            .fontColor('#333333') // 文字颜色
            .fontWeight(600) // 粗细:100(极细)-900(极粗),默认400
            .fontFamily('HarmonyOS Sans') // 字体(需系统支持)
            .textAlign(TextAlign.Center) // 文字对齐:Left/Center/Right
            .width('100%')
            .height(60)
            .backgroundColor('#F5F5F5')
    
          Text("这是一段超过一行的文本,需要设置换行和最大行数,否则会超出容器范围")
            .fontSize(18)
            .maxLines(2) // 最大行数
            .lineHeight(24) // 行高
            .textOverflow({ overflow: TextOverflow.Ellipsis }) // 超出部分显示省略号
            .width('100%')
            .padding(10)
            .backgroundColor('#EEEEEE')
        }
        .width('100%')
        .padding(20)
      }
    }

    (2)Image图片组件
    @Entry
    @Component
    struct ImageFullDemo {
      build() {
        Column({ space: 20 }) {
          // 1. 本地图片
          Image($r('app.media.background')) // 路径规则:app.media.文件名(无后缀)
            .width(120)
            .height(120)
            .objectFit(ImageFit.Cover) // 图片适配方式:Cover(裁剪填充满)
            .borderRadius(60) // 圆形图片(宽高相等+圆角为宽高的一半)
            .backgroundColor('#F0F0F0')
          // 2. 网络图片
          Image('https://p2.ssl.qhimgs1.com/t040ceea1a9af1387a8.jpg')
            .width(200)
            .height(100)
            .objectFit(ImageFit.Contain) // 适配方式:Contain(完整显示,不裁剪)
            .margin({ top: 10 })
            .alt($r('app.media.startIcon')) // 加载失败时显示的兜底图片
        }
        .width('100%')
        .padding(20)
        .height('100%')
        .justifyContent(FlexAlign.Center)
      }
    }

    (3)Button按钮组件
    @Entry
    @Component
    struct ButtonDemo {
      build() {
        Column({ space: 15 }) {
          // 普通按钮
          Button("普通按钮")
            .width(150)
            .height(45)
            .fontSize(18)
            .backgroundColor(Color.Blue)
            .fontColor(Color.White)
            .borderRadius(8)
    
          // 带图标按钮(用Row+Image+Text实现)
          Row() {
            Image($r('app.media.startIcon')) 
              .width(20)
              .height(20)
              .margin({ right: 8 })
            Text("带图标按钮")
              .fontSize(18)
              .fontColor(Color.White)
          }
          .width(150)
          .height(45)
          .justifyContent(FlexAlign.Center)
          .backgroundColor(Color.Green)
          .borderRadius(8)
          .onClick(() => {
            // 点击事件
          })
        }
        .width('100%')
        .padding(20)
        .height('100%')
        .justifyContent(FlexAlign.Center)
      }
    }

    四、实战布局:黑马云音乐

    1. 实操步骤

    1. 第一步:搭建整体框架 → 根容器Column,设置padding、安全区;

    2. 第二步:添加标题 → Text组件做标题,设置字体、边距;

    3. 第三步:构建滚动列表 → List+ListItem实现滚动,绑定模拟数据;

    4. 第四步:列表项布局 → 每个ListItem内用Row做横向布局,包含图片+文本+按钮;

    5. 第五步:美化样式 → 给组件加边距、圆角、边框、对齐方式;

    6. 第六步:适配优化 → 用layoutWeight、expandSafeArea提升适配性。

    2. 完整可运行代码

    // 实操步骤1:定义数据接口(先规范数据格式,避免类型推断报错,为后续数据渲染打基础)
    // 接口作用:明确歌曲对象的结构,规定每个字段的类型,让代码更规范、易维护
    interface MusicItem {
      id: number;       // 歌曲唯一标识
      name: string;     // 歌曲名称
      singer: string;   // 歌手名称
      cover: Resource;  // 歌曲封面(Resource类型,适配本地资源引用$r())
    }
    
    // 实操步骤2:创建入口组件(整个页面的核心容器,@Entry标记为应用入口)
    @Entry
    @Component
    struct MusicGuessLike {
      // 实操步骤3:定义并初始化歌曲数据
      private musicList: MusicItem[] = [
        // 本地资源引用规则:$r('app.media.资源名'),需将图片放入resources/base/media目录
        { id: 1, name: "七里香", singer: "周杰伦", cover: $r('app.media.1') },
        { id: 2, name: "小幸运", singer: "田馥甄", cover: $r('app.media.2') },
        { id: 3, name: "起风了", singer: "买辣椒也用券", cover: $r('app.media.3') },
        { id: 4, name: "花海", singer: "周杰伦", cover: $r('app.media.4') },
        { id: 5, name: "告白气球", singer: "周杰伦", cover: $r('app.media.5') }
      ];
    
      // 实操步骤4:编写UI渲染入口(build()方法是所有界面代码的入口,必须包含根容器)
      build() {
        // 实操步骤5:搭建页面根容器(使用Column垂直布局,作为页面最外层框架,占满整个屏幕)
        Column() {
          // 实操步骤6:制作标题区域(页面顶部标题,设置样式使其醒目、贴合布局)
          Text("猜你喜欢")
            .fontSize(32)          // 标题字号(稍大,突出标题层级)
            .fontWeight(800)       // 字体加粗,增强视觉效果
            .fontColor('#333333')  // 标题颜色(深灰,避免刺眼)
            .width('100%')         // 标题占满父容器宽度,左右对齐
            .margin({ bottom: 20 }); // 与下方列表拉开间距,避免拥挤
    
          // 实操步骤7:搭建滚动列表容器(使用List组件,实现超出屏幕时可滚动的效果)
          List() {
            // 实操步骤8:循环渲染列表项(使用ForEach遍历歌曲数据,批量生成列表项)
            ForEach(
              this.musicList, // 遍历的数据源:上面定义的歌曲数组
              // 实操步骤9:处理单个列表项的UI布局(显式指定item类型为MusicItem,避免类型警告)
              (item: MusicItem) => {
                // 实操步骤10:包裹单个列表项(List的子组件必须是ListItem,否则无法正常渲染)
                ListItem() {
                  // 实操步骤11:设计列表项内部布局(Row水平布局,包含封面、歌曲信息、播放按钮)
                  Row({ space: 15 }) { // space:子组件之间的间距,避免拥挤
                    // 实操步骤12:添加歌曲封面(Image组件加载本地资源,设置样式适配布局)
                    Image(item.cover)
                      .width(64)                // 封面宽度,固定尺寸保证布局整齐
                      .height(64)               // 封面高度,与宽度一致,避免拉伸
                      .borderRadius(8)          // 轻微圆角,提升美观度
                      .objectFit(ImageFit.Cover); // 图片适配方式:裁剪填充满容器,保持比例
    
                    // 实操步骤13:添加歌曲信息区域(Column垂直布局,展示歌曲名和歌手名)
                    Column({ space: 5 }) { // space:歌曲名与歌手名的间距,区分层级
                      // 歌曲名样式:稍大、加粗,突出显示
                      Text(item.name)
                        .fontSize(18)
                        .fontWeight(600)
                        .fontColor('#333333');
                      // 歌手名样式:稍小、浅灰,作为辅助信息
                      Text(item.singer)
                        .fontSize(14)
                        .fontColor('#999999');
                    }
                    .layoutWeight(1) // 占满Row剩余宽度,适配不同屏幕
                    .alignItems(HorizontalAlign.Start); // 文字左对齐,符合阅读习惯
    
                    // 实操步骤14:添加播放按钮(用Text组件模拟,占位使用)
                    Text("▶")
                      .fontSize(22)              // 按钮大小适中
                      .fontColor('#666666')      // 颜色柔和,不抢焦点
                      .width(40)                 // 固定宽高,保证按钮方正
                      .height(40)
                      .textAlign(TextAlign.Center); // 符号居中,提升美观度
                  }
                  // 实操步骤15:美化列表项(添加内边距、背景色、圆角,提升视觉体验)
                  .padding(12) // 列表项内边距,内容与边框拉开距离
                  .backgroundColor('#F8F8F8') // 浅灰背景,区分不同列表项
                  .borderRadius(12) // 圆角设计,避免尖锐边角
                  .margin({ bottom: 10 }); // 列表项之间的间距,避免粘连
                }
              },
              // 实操步骤16:设置列表项唯一标识(用歌曲id转换为字符串,避免列表刷新异常)
              (item: MusicItem) => item.id.toString()
            );
          }
          // 实操步骤17:设置列表样式(优化滚动体验和布局适配)
          .scrollBar(BarState.Off) // 隐藏滚动条,提升页面美观度
          .layoutWeight(1) // 占满Column剩余高度,适配不同屏幕高度
          .alignListItem(ListItemAlign.Center) // 列表项在List中居中对齐,布局更整齐
          .width('100%') // 列表占满父容器宽度,避免留白
          .height('100%'); // 显式设置宽高,消除IDE警告
        }
          // 实操步骤18:设置根容器样式(保证页面占满屏幕,适配全面屏,优化整体布局)
          .width('100%')                          // 根容器占满屏幕宽度
            .height('100%')                         // 根容器占满屏幕高度
            .padding({ top: 20, left: 20, right: 20, bottom: 20 }) // 页面内边距,避免内容贴边
            .expandSafeArea([SafeAreaType.SYSTEM])  // 扩充系统安全区,适配刘海屏/底部导航栏
            .backgroundColor('#FFFFFF');            // 页面背景色设为白色,简洁干净
        }
      }
    

    Logo

    作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

    更多推荐