ArkUI 基础组件上手:文本、图片、按钮与输入框

组件是界面的基本单位

ArkUI 的系统组件就是界面里的"零件"——文本框、图片、按钮、输入框、单选框、进度条这些。把它们组合起来,就拼出一个完整页面。这系列先讲最常用的几类:文本、图片、按钮、输入框,以及承载它们的通用属性。

文本组件 Text

Text 是最基础的组件,显示一段文字。常用的需求:字号、颜色、粗细、对齐、行数截断。

@Entry
@Component
struct TextDemo {
  build() {
    Column({ space: 12 }) {
      // 基础文本:字号和颜色
      Text('这是一段基础文本')
        .fontSize(18)
        .fontColor('#333333')

      // 加粗 + 对齐
      Text('加粗标题')
        .fontSize(24)
        .fontWeight(FontWeight.Bold)
        .textAlign(TextAlign.Center)

      // 省略号:超过两行显示 ...
      Text('这是一段很长很长的文本,用来演示超长内容的省略处理,超过两行之后就会显示省略号')
        .fontSize(14)
        .maxLines(2)
        .textOverflow({ overflow: TextOverflow.Ellipsis })  // 超出显示省略号

      // 富文本:不同片段不同样式
      Text() {
        Span('普通文字')
        Span('高亮文字').fontColor(Color.Red)  // Span 局部样式
        Span('加粗').fontWeight(FontWeight.Bold)
      }
    }
    .padding(16)
  }
}

几个要点:

  • fontSize 默认单位是 vp,数字即可
  • 超长文本用 maxLines + textOverflow 控制截断
  • 需要局部样式用 Span 拼富文本,而不是多个 Text

图片组件 Image

Image 显示图片,支持本地资源和网络图片。核心是图片加载方式和缩放模式。

@Entry
@Component
struct ImageDemo {
  build() {
    Column({ space: 12 }) {
      // 本地资源:$r 引用 resources 目录下的资源
      Image($r('app.media.logo'))
        .width(120)
        .height(120)

      // 网络图片:需要申请 ohos.permission.INTERNET 权限
      Image('https://example.com/banner.jpg')
        .width(300)
        .height(150)
        .objectFit(ImageFit.Cover)  // 缩放填满并裁剪

      // 不同缩放模式
      Image($r('app.media.photo'))
        .width(200)
        .height(200)
        .objectFit(ImageFit.Contain)  // 完整显示,留白
    }
    .padding(16)
  }
}

objectFit 的常用值:

效果
Contain完整显示图片,可能留白
Cover填满容器,可能裁剪
Fill拉伸填满,可能变形
None原始尺寸,不缩放

图片按比例展示用 Contain(头像、商品图),做 banner 覆盖用 Cover。

按钮组件 Button

Button 触发操作。除了默认样式,可以自定义背景、圆角,支持多种类型的点击状态。

@Entry
@Component
struct ButtonDemo {
  build() {
    Column({ space: 12 }) {
      // 基础按钮
      Button('确定')
        .width(200)
        .height(48)

      // 胶囊按钮:圆角 = 高度一半
      Button('登录')
        .width(260)
        .height(52)
        .type(ButtonType.Capsule)  // 胶囊形状

      // 自定义背景和圆角
      Button('立即购买')
        .width(240)
        .height(48)
        .backgroundColor('#FF6B35')
        .borderRadius(8)
        .fontColor(Color.White)
        .onClick(() => {
          // 点击回调
        })

      // 禁用状态
      Button('已售罄')
        .enabled(false)  // 禁用,不可点击
    }
    .padding(16)
  }
}

按钮类型 typeCapsule(胶囊)、Circle(圆形)、Normal(默认)。配合 enabled 可以做权限/状态的禁用效果。

输入框 TextInput

TextInput 是单行输入框,处理用户输入的核心是监听变化和获取内容。

@Entry
@Component
struct InputDemo {
  @State username: string = '';
  @State password: string = '';

  build() {
    Column({ space: 16 }) {
      // 普通输入框
      TextInput({ placeholder: '请输入用户名' })
        .onChange((value: string) => {
          this.username = value;  // 监听输入变化
        })

      // 密码框:输入内容隐藏
      TextInput({ placeholder: '请输入密码' })
        .type(InputType.Password)  // 密码类型
        .onChange((value: string) => {
          this.password = value;
        })

      // 带清除按钮
      TextInput({ placeholder: '搜索' })
        .showUnderline(false)  // 去下划线
        .backgroundColor('#F5F5F5')
        .borderRadius(8)

      // 显示当前输入(状态驱动刷新)
      Text(`用户名:${this.username}`)
    }
    .padding(16)
  }
}

TextInput 的类型 InputTypeNormalPasswordEmailNumberPhoneNumber。输入监听用 onChange,拿到最新输入值写回 @State

单选与勾选

表单里常用的选择组件:

@Entry
@Component
struct ChoiceDemo {
  @State gender: number = 0;
  @State agree: boolean = false;

  build() {
    Column({ space: 8 }) {
      // 单选框
      Row() {
        Radio({ value: 'male', group: 'gender' })
          .checked(this.gender === 0)
          .onChange((checked: boolean) => {
            if (checked) this.gender = 0;
          })
        Text('男')
      }
      Row() {
        Radio({ value: 'female', group: 'gender' })
          .checked(this.gender === 1)
          .onChange((checked: boolean) => {
            if (checked) this.gender = 1;
          })
        Text('女')
      }

      // 复选框
      Row() {
        Checkbox()
          .select(this.agree)
          .onChange((checked: boolean) => {
            this.agree = checked;
          })
        Text('我已阅读并同意用户协议')
      }
    }
    .padding(16)
  }
}

单选框 Radiogroup 字段分组,同组互斥。复选框 Checkboxselect 控制选中状态。

进度条 Progress

Progress 展示进度,有线性、环形等多种样式:

@Entry
@Component
struct ProgressDemo {
  @State value: number = 40;

  build() {
    Column({ space: 16 }) {
      // 线性进度条
      Progress({ value: this.value, total: 100, type: ProgressType.Linear })
        .width(300)
        .color('#FF6B35')

      // 环形进度条
      Progress({ value: this.value, total: 100, type: ProgressType.Ring })

      // 加载中的不确定进度
      Progress({ value: 0, total: 100, type: ProgressType.Linear })
        .style(ProgressStyle.Capsule)  // 胶囊样式
    }
    .padding(16)
  }
}

通用属性:每个组件都能用

有些属性几乎每个组件都支持,理解它们能少记很多东西:

属性作用
width / height尺寸,默认单位 vp
margin / padding外边距 / 内边距
backgroundColor背景色
borderRadius圆角
opacity透明度
visibility可见性(Hidden 占位不可见 / None 不占位)
onClick点击事件
enabled是否可用

这些通用属性配组件专属属性使用。比如按钮能用 borderRadius 调圆角,文本也能用,不用来回查文档。

一点组件实践小经验

  1. 文本超长一定要处理截断。列表里的标题、描述不设 maxLines,超长会撑破布局。回到列表场景,Text 的省略号是高频需求。

  2. 图片记得设置尺寸和 objectFit。不设尺寸图片可能显示异常,不设 objectFit 默认拉伸会变形。

  3. 输入框状态要及时写回onChange 里同步 @State,否则后续逻辑拿到的是旧值。

  4. 通用属性优先于组件特有属性。先把通用属性记熟,能覆盖大部分需求,组件特有属性用到再查。

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐