ArkTS第三章:声明式UI开发实战

文章三:声明式UI开发实战

🔥 关键词:ArkUI、声明式UI、鸿蒙布局、组件开发

前言

声明式UI是现代前端开发的主流范式,ArkUI作为HarmonyOS的声明式UI框架,让开发者可以用简洁的代码描述界面"应该是什么样子",而不是"如何变成那样"。

本文将通过实战案例,带你掌握ArkUI的核心概念和常用组件。


一、声明式UI核心理念

声明式UI与传统命令式UI的区别:

typescript 复制代码
// 命令式(传统方式)
// 1. 获取按钮引用
// 2. 设置点击监听器
// 3. 在回调中修改文本内容
button.setOnClickListener {
    textView.text = 'Clicked!'
}

// 声明式(ArkUI方式)
@State message: string = 'Click me'
...
Text(this.message)
  .onClick(() => {
    this.message = 'Clicked!'
  })

二、基础布局组件

2.1 Column和Row

typescript 复制代码
@Entry
@Component
struct LayoutDemo {
  build() {
    Column({ space: 20 }) {  // 垂直排列,间距20
      Text('第一行').fontSize(20)
      Text('第二行').fontSize(20)
      
      Row({ space: 20 }) {   // 水平排列
        Text('左').fontSize(20)
        Text('中').fontSize(20)
        Text('右').fontSize(20)
      }
    }
    .width('100%')
    .height('100%')
    .justifyContent(FlexAlign.Center)
  }
}

2.2 Flex布局

typescript 复制代码
Flex({
  direction: FlexDirection.Row,      // 主轴方向
  wrap: FlexWrap.Wrap,                // 换行
  justifyContent: FlexAlign.SpaceBetween,  // 主轴对齐
  alignItems: ItemAlign.Center        // 交叉轴对齐
}) {
  // 子组件
  ForEach([1, 2, 3, 4, 5], (item) => {
    Text(`Item ${item}`)
      .width(80)
      .height(80)
      .backgroundColor('#3B82F6')
      .fontColor(Color.White)
      .textAlign(TextAlign.Center)
  })
}

三、常用UI组件

3.1 文本组件Text

typescript 复制代码
Text('Hello HarmonyOS')
  .fontSize(24)                    // 字体大小
  .fontWeight(FontWeight.Bold)      // 字体粗细
  .fontColor('#3B82F6')             // 字体颜色
  .textAlign(TextAlign.Center)      // 文本对齐
  .maxLines(2)                      // 最大行数
  .textOverflow({ overflow: TextOverflow.Ellipsis })  // 溢出处理

3.2 按钮组件Button

typescript 复制代码
Button('点击我', { type: ButtonType.Capsule })
  .width(200)
  .height(50)
  .fontSize(18)
  .fontColor(Color.White)
  .backgroundColor('#3B82F6')
  .onClick(() => {
    console.info('Button clicked!')
  })

// 自定义按钮内容
Button() {
  Row({ space: 10 }) {
    Image($r('app.media.icon')).width(20).height(20)
    Text('带图标的按钮').fontColor(Color.White)
  }
}
.type(ButtonType.Circle)
.backgroundColor('#6366F1')

3.3 图片组件Image

typescript 复制代码
// 加载本地资源
Image($r('app.media.logo'))
  .width(100)
  .height(100)
  .objectFit(ImageFit.Cover)       // 填充模式
  .borderRadius(10)                // 圆角

// 加载网络图片
Image('https://example.com/image.png')
  .width(200)
  .height(150)
  .alt($r('app.media.placeholder'))  // 占位图

3.4 输入组件TextInput

typescript 复制代码
@State username: string = ''

TextInput({ placeholder: '请输入用户名' })
  .width('80%')
  .height(50)
  .backgroundColor('#F1F5F9')
  .borderRadius(8)
  .padding({ left: 15, right: 15 })
  .type(InputType.Normal)           // 输入类型
  .onChange((value) => {
    this.username = value
  })

四、列表组件

4.1 List和ListItem

typescript 复制代码
@State items: string[] = ['苹果', '香蕉', '橙子', '葡萄', '西瓜']

List({ space: 10 }) {
  ForEach(this.items, (item, index) => {
    ListItem() {
      Row() {
        Text(item)
          .fontSize(18)
          .layoutWeight(1)
        
        Button('删除')
          .fontSize(14)
          .backgroundColor('#EF4444')
          .onClick(() => {
            this.items.splice(index, 1)
          })
      }
      .width('100%')
      .padding(15)
      .backgroundColor(Color.White)
      .borderRadius(8)
      .shadow({ radius: 4, color: '#00000010' })
    }
  })
}
.width('100%')
.height('100%')
.padding(15)

五、实战:登录界面

综合运用所学知识,实现一个精美的登录界面:

typescript 复制代码
@Entry
@Component
struct LoginPage {
  @State username: string = ''
  @State password: string = ''
  @State isLoading: boolean = false

  build() {
    Column({ space: 20 }) {
      // Logo区域
      Column({ space: 10 }) {
        Image($r('app.media.logo'))
          .width(80)
          .height(80)
          .borderRadius(20)
        
        Text('欢迎登录')
          .fontSize(24)
          .fontWeight(FontWeight.Bold)
      }
      .margin({ top: 80, bottom: 40 })

      // 输入区域
      Column({ space: 15 }) {
        TextInput({ placeholder: '用户名', text: this.username })
          .width('85%')
          .height(50)
          .backgroundColor('#F8FAFC')
          .borderRadius(10)
          .onChange((value) => this.username = value)
        
        TextInput({ placeholder: '密码', text: this.password })
          .width('85%')
          .height(50)
          .type(InputType.Password)
          .backgroundColor('#F8FAFC')
          .borderRadius(10)
          .onChange((value) => this.password = value)
      }

      // 登录按钮
      Button(this.isLoading ? '登录中...' : '登 录')
        .width('85%')
        .height(50)
        .fontSize(18)
        .fontColor(Color.White)
        .backgroundColor('#3B82F6')
        .borderRadius(10)
        .enabled(!this.isLoading && this.username !== '' && this.password !== '')
        .onClick(() => this.handleLogin())
        .margin({ top: 30 })
    }
    .width('100%')
    .height('100%')
    .backgroundColor(Color.White)
  }

  handleLogin() {
    this.isLoading = true
    // 模拟登录请求
    setTimeout(() => {
      this.isLoading = false
      console.info('登录成功')
    }, 2000)
  }
}

总结

本文详细介绍了ArkUI的声明式UI开发方式,包括基础布局、常用组件和列表组件的使用。通过登录界面的实战案例,展示了如何将这些知识综合运用。

下一篇文章将深入讲解状态管理,让你的应用数据流动更加清晰可控。


相关推荐
landuochong2002 小时前
用 Claude Code 直接写 Obsidian 笔记-增强版
人工智能·笔记·skill·claudecode
带刺的坐椅2 小时前
RFC 9535:JSONPath 的标准化之路
java·json·jsonpath·snack4·rfc9535
Elastic 中国社区官方博客2 小时前
Elasticsearch:运用 JINA 来实现多模态搜索的 RAG
大数据·人工智能·elasticsearch·搜索引擎·ai·全文检索·jina
码小瑞2 小时前
画布文字在不同缩放屏幕上的归一化
前端
神の愛2 小时前
java日志功能
java·开发语言·前端
永霖光电_UVLED2 小时前
氧化镓高体积热容的特性,集成高介电常数界面的结侧冷却架构
人工智能·生成对抗网络·架构·汽车·制造
小李子呢02112 小时前
前端八股(1)--Promise 常用方法有哪些?和async和await的区别
前端
世人万千丶2 小时前
Flutter 框架跨平台鸿蒙开发 - 嫉妒分析器应用
学习·flutter·华为·开源·harmonyos·鸿蒙
lishutong10062 小时前
基于 Perfetto 与 AI 的 Android 性能自动化诊断方案
android·人工智能·自动化