HarmonyOS基础组件宝典:Text、Image、Button的全面应用

本文将深入讲解HarmonyOS中最常用的三大基础组件:Text、Image和Button,通过丰富的示例展示它们的完整用法和高级特性。

一、Text文本组件详解

1.1 基础文本显示

@Component
struct TextBasicExample {
  build() {
    Column({ space: 15 }) {
      // 基础文本
      Text('普通文本')
        .fontSize(16)
        .fontColor(Color.Black)
      
      // 多行文本
      Text('这是一个很长的文本内容,需要自动换行显示。HarmonyOS提供了完善的文本布局能力。')
        .fontSize(14)
        .maxLines(3) // 最大行数
        .textOverflow({ overflow: TextOverflow.Ellipsis }) // 超出显示省略号
        .textAlign(TextAlign.Start)
      
      // 富文本
      Text() {
        Span('红色文字')
          .fontColor(Color.Red)
          .fontSize(18)
          .fontWeight(FontWeight.Bold)
        
        Span(' | ')
          .fontColor(Color.Gray)
        
        Span('蓝色文字')
          .fontColor(Color.Blue)
          .fontSize(16)
          .textDecoration({ type: TextDecorationType.Underline })
      }
      .fontSize(16)
    }
    .width('100%')
    .padding(20)
  }
}

1.2 文本样式与装饰

@Component
struct TextStyleExample {
  @State isBold: boolean = false
  @State isItalic: boolean = false
  @State textSize: number = 16

  build() {
    Column({ space: 20 }) {
      // 动态样式文本
      Text('动态样式文本示例')
        .fontSize(this.textSize)
        .fontWeight(this.isBold ? FontWeight.Bold : FontWeight.Normal)
        .fontStyle(this.isItalic ? FontStyle.Italic : FontStyle.Normal)
        .fontColor('#007DFF')
        .backgroundColor('#F0F8FF')
        .padding(10)
        .borderRadius(8)
        .textAlign(TextAlign.Center)
        .width('100%')
      
      // 文本装饰效果
      Text('删除线文本')
        .fontSize(16)
        .textDecoration({
          type: TextDecorationType.LineThrough,
          color: Color.Red
        })
      
      Text('下划线文本')
        .fontSize(16)
        .textDecoration({
          type: TextDecorationType.Underline,
          color: Color.Blue
        })
      
      // 文本阴影
      Text('阴影效果文本')
        .fontSize(20)
        .fontWeight(FontWeight.Bold)
        .fontColor(Color.White)
        .textShadow({
          radius: 4,
          color: Color.Gray,
          offsetX: 2,
          offsetY: 2
        })
        .backgroundColor('#4A90E2')
        .padding(10)
        .borderRadius(8)
      
      // 控制按钮
      Row({ space: 10 }) {
        Button('加粗')
          .onClick(() => this.isBold = !this.isBold)
          .stateEffect(this.isBold)
        
        Button('斜体')
          .onClick(() => this.isItalic = !this.isItalic)
          .stateEffect(this.isItalic)
        
        Button('增大')
          .onClick(() => this.textSize += 2)
        
        Button('减小')
          .onClick(() => this.textSize -= 2)
      }
      .width('100%')
      .justifyContent(FlexAlign.SpaceAround)
    }
    .width('100%')
    .padding(20)
  }
}

1.3 高级文本特性

@Component
struct TextAdvancedExample {
  @State content: string = `HarmonyOS是华为推出的分布式操作系统,致力于为不同设备的智能化、互联与协同提供统一的语言。

主要特性:
• 分布式架构
• 一次开发,多端部署
• 统一生态`

  build() {
    Column({ space: 15 }) {
      // 可复制文本
      Text(this.content)
        .fontSize(14)
        .textAlign(TextAlign.Start)
        .copyOption(CopyOptions.LocalDevice) // 允许复制
        .onCopy((value: string) => {
          console.log('复制的内容:', value)
        })
      
      // 文本选择
      Text('长按可选择文本')
        .fontSize(16)
        .textSelection({ enabled: true }) // 启用文本选择
        .onSelectionChange((start: number, end: number) => {
          console.log(`选择范围: ${start} - ${end}`)
        })
      
      // 自适应文本
      Text('自适应大小文本')
        .fontSize(20)
        .maxFontScale(2.0) // 最大缩放倍数
        .minFontScale(0.5) // 最小缩放倍数
        .lineHeight(30)
        .adaptTextHeight(true) // 自适应高度
      
      // 多语言文本
      Text($r('app.string.welcome_message'))
        .fontSize(18)
        .fontColor($r('app.color.primary'))
    }
    .width('100%')
    .padding(20)
  }
}

二、Image图片组件详解

2.1 基础图片显示

@Component
struct ImageBasicExample {
  // 图片资源
  private localImage: Resource = $r('app.media.logo')
  private networkImage: string = 'https://example.com/image.jpg'
  private base64Image: string = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUg...'

  build() {
    Column({ space: 20 }) {
      // 本地图片
      Text('本地图片:').fontSize(16).fontColor('#666')
      Image(this.localImage)
        .width(100)
        .height(100)
        .borderRadius(8)
        .overlay('本地', {
          align: Alignment.Bottom,
          offset: { x: 0, y: 10 }
        })
      
      // 网络图片
      Text('网络图片:').fontSize(16).fontColor('#666')
      Image(this.networkImage)
        .width(120)
        .height(120)
        .borderRadius(12)
        .alt($r('app.media.placeholder')) // 加载失败时显示
        .onComplete((msg: string) => {
          console.log('图片加载完成')
        })
        .onError(() => {
          console.log('图片加载失败')
        })
      
      // Base64图片
      Text('Base64图片:').fontSize(16).fontColor('#666')
      Image(this.base64Image)
        .width(80)
        .height(80)
        .interpolation(ImageInterpolation.High) // 高质量插值
    }
    .width('100%')
    .padding(20)
    .alignItems(HorizontalAlign.Start)
  }
}

2.2 图片样式与效果

@Component
struct ImageStyleExample {
  @State borderRadius: number = 0
  @State opacity: number = 1.0
  @State rotation: number = 0
  @State scale: number = 1.0

  build() {
    Column({ space: 20 }) {
      // 动态效果图片
      Image($r('app.media.sample'))
        .width(150)
        .height(150)
        .borderRadius(this.borderRadius)
        .opacity(this.opacity)
        .rotate({ angle: this.rotation })
        .scale({ x: this.scale, y: this.scale })
        .shadow({ radius: 10, color: Color.Gray, offsetX: 5, offsetY: 5 })
        .overlay('动态效果', {
          align: Alignment.Center,
          style: {
            fontSize: 16,
            fontColor: Color.White,
            backgroundColor: '#80000000'
          }
        })
      
      // 控制面板
      this.buildControlPanel()
    }
    .width('100%')
    .padding(20)
  }

  @Builder
  buildControlPanel() {
    Column({ space: 10 }) {
      Text('图片样式控制').fontSize(18).fontWeight(FontWeight.Bold)
      
      // 圆角控制
      Text(`圆角: ${this.borderRadius}`).fontSize(14)
      Slider({
        value: this.borderRadius,
        min: 0,
        max: 75,
        step: 1,
        style: SliderStyle.OutSet
      })
      .onChange((value: number) => {
        this.borderRadius = value
      })
      
      // 透明度控制
      Text(`透明度: ${this.opacity.toFixed(1)}`).fontSize(14)
      Slider({
        value: this.opacity,
        min: 0.1,
        max: 1.0,
        step: 0.1
      })
      .onChange((value: number) => {
        this.opacity = value
      })
      
      // 旋转控制
      Text(`旋转: ${this.rotation}°`).fontSize(14)
      Slider({
        value: this.rotation,
        min: 0,
        max: 360,
        step: 15
      })
      .onChange((value: number) => {
        this.rotation = value
      })
      
      // 缩放控制
      Text(`缩放: ${this.scale.toFixed(1)}`).fontSize(14)
      Slider({
        value: this.scale,
        min: 0.5,
        max: 2.0,
        step: 0.1
      })
      .onChange((value: number) => {
        this.scale = value
      })
    }
    .width('100%')
    .padding(15)
    .backgroundColor('#F8F9FA')
    .borderRadius(12)
  }
}

2.3 图片加载与缓存

@Component
struct ImageAdvancedExample {
  @State imageList: string[] = [
    'https://picsum.photos/200/300?random=1',
    'https://picsum.photos/200/300?random=2',
    'https://picsum.photos/200/300?random=3',
    'https://picsum.photos/200/300?random=4'
  ]
  @State currentImage: string = ''
  @State isLoading: boolean = false
  @State loadProgress: number = 0

  build() {
    Column({ space: 20 }) {
      // 图片显示区域
      Stack() {
        if (this.currentImage) {
          Image(this.currentImage)
            .width(200)
            .height(300)
            .objectFit(ImageFit.Cover)
            .borderRadius(12)
            .transition({ type: TransitionType.Insert, opacity: 0 })
            .transition({ type: TransitionType.Delete, opacity: 0 })
        } else {
          Text('点击加载图片')
            .fontSize(16)
            .fontColor('#666')
            .width(200)
            .height(300)
            .backgroundColor('#F0F0F0')
            .textAlign(TextAlign.Center)
            .borderRadius(12)
        }
        
        // 加载指示器
        if (this.isLoading) {
          Progress({ value: this.loadProgress, total: 100 })
            .width(200)
            .color(Color.Blue)
        }
      }
      
      // 图片列表
      Scroll() {
        Row({ space: 10 }) {
          ForEach(this.imageList, (imageUrl: string, index: number) => {
            Image(imageUrl)
              .width(60)
              .height(60)
              .objectFit(ImageFit.Cover)
              .borderRadius(8)
              .onClick(() => {
                this.loadImage(imageUrl)
              })
              .overlay(`图${index + 1}`, {
                align: Alignment.Bottom,
                style: {
                  fontSize: 10,
                  fontColor: Color.White,
                  backgroundColor: '#80000000'
                }
              })
          })
        }
        .padding(10)
      }
      .height(80)
    }
    .width('100%')
    .padding(20)
    .onClick(() => {
      if (!this.currentImage) {
        this.loadImage(this.imageList[0])
      }
    })
  }

  loadImage(url: string) {
    this.isLoading = true
    this.loadProgress = 0
    this.currentImage = ''
    
    // 模拟图片加载过程
    const simulateLoad = setInterval(() => {
      this.loadProgress += 10
      if (this.loadProgress >= 100) {
        clearInterval(simulateLoad)
        this.currentImage = url
        this.isLoading = false
        this.loadProgress = 0
      }
    }, 100)
  }
}

三、Button按钮组件详解

3.1 基础按钮类型

@Component
struct ButtonBasicExample {
  @State clickCount: number = 0

  build() {
    Column({ space: 15 }) {
      Text('按钮类型示例').fontSize(20).fontWeight(FontWeight.Bold)
      
      // 主要按钮
      Button('主要按钮', { type: ButtonType.Capsule })
        .width('100%')
        .height(40)
        .backgroundColor('#007DFF')
        .fontColor(Color.White)
        .fontSize(16)
        .onClick(() => {
          this.clickCount++
          console.log('主要按钮被点击')
        })
      
      // 次要按钮
      Button('次要按钮', { type: ButtonType.Normal })
        .width('100%')
        .height(40)
        .backgroundColor('#34C759')
        .fontColor(Color.White)
        .fontSize(16)
      
      // 圆形按钮
      Button('圆', { type: ButtonType.Circle })
        .width(60)
        .height(60)
        .backgroundColor('#FF9500')
        .fontColor(Color.White)
      
      // 边框按钮
      Button('边框按钮')
        .width('100%')
        .height(40)
        .border({ width: 2, color: '#007DFF' })
        .backgroundColor(Color.Transparent)
        .fontColor('#007DFF')
      
      // 禁用状态按钮
      Button('禁用按钮')
        .width('100%')
        .height(40)
        .enabled(false) // 禁用按钮
        .backgroundColor('#C6C6C8')
        .fontColor('#8E8E93')
      
      // 点击计数显示
      Text(`按钮被点击了 ${this.clickCount} 次`)
        .fontSize(14)
        .fontColor('#666')
        .margin({ top: 20 })
    }
    .width('100%')
    .padding(20)
  }
}

3.2 按钮样式与状态

@Component
struct ButtonStyleExample {
  @State buttonStyle: ButtonType = ButtonType.Normal
  @State buttonSize: string = 'medium'
  @State isPressed: boolean = false

  build() {
    Column({ space: 20 }) {
      // 动态样式按钮
      Button('动态样式按钮')
        .width(this.getButtonWidth())
        .height(this.getButtonHeight())
        .backgroundColor(this.getButtonColor())
        .fontColor(Color.White)
        .fontSize(this.getFontSize())
        .borderRadius(this.getBorderRadius())
        .stateEffect(true) // 启用状态效果
        .onClick(() => {
          console.log('按钮被点击')
        })
        .onTouch((event: TouchEvent) => {
          this.isPressed = event.type === TouchType.Down
        })
      
      // 图标按钮
      Button() {
        Row({ space: 5 }) {
          Image($r('app.media.icon_heart'))
            .width(20)
            .height(20)
            .fillColor(Color.White)
          
          Text('图标按钮')
            .fontColor(Color.White)
            .fontSize(16)
        }
      }
      .width(120)
      .height(44)
      .backgroundColor('#FF2D6D')
      .borderRadius(22)
      
      // 按钮组控制
      this.buildControlPanel()
    }
    .width('100%')
    .padding(20)
  }

  @Builder
  buildControlPanel() {
    Column({ space: 10 }) {
      Text('按钮样式控制').fontSize(16).fontWeight(FontWeight.Bold)
      
      // 按钮类型选择
      Row({ space: 10 }) {
        ForEach([ButtonType.Normal, ButtonType.Capsule, ButtonType.Circle], (type: ButtonType) => {
          Button(this.getTypeName(type))
            .layoutWeight(1)
            .stateEffect(this.buttonStyle === type)
            .onClick(() => this.buttonStyle = type)
        })
      }
      
      // 按钮尺寸选择
      Row({ space: 10 }) {
        ForEach(['small', 'medium', 'large'], (size: string) => {
          Button(size)
            .layoutWeight(1)
            .stateEffect(this.buttonSize === size)
            .onClick(() => this.buttonSize = size)
        })
      }
    }
    .width('100%')
    .padding(15)
    .backgroundColor('#F8F9FA')
    .borderRadius(12)
  }

  getButtonWidth(): string | number {
    switch (this.buttonSize) {
      case 'small': return 100
      case 'medium': return 140
      case 'large': return 180
      default: return 140
    }
  }

  getButtonHeight(): number {
    switch (this.buttonSize) {
      case 'small': return 32
      case 'medium': return 40
      case 'large': return 48
      default: return 40
    }
  }

  getButtonColor(): string {
    return this.isPressed ? '#0056CC' : '#007DFF'
  }

  getFontSize(): number {
    switch (this.buttonSize) {
      case 'small': return 12
      case 'medium': return 14
      case 'large': return 16
      default: return 14
    }
  }

  getBorderRadius(): number {
    return this.buttonStyle === ButtonType.Capsule ? 20 : 8
  }

  getTypeName(type: ButtonType): string {
    switch (type) {
      case ButtonType.Normal: return '普通'
      case ButtonType.Capsule: return '胶囊'
      case ButtonType.Circle: return '圆形'
      default: return '未知'
    }
  }
}

3.3 高级按钮功能

@Component
struct ButtonAdvancedExample {
  @State isLoading: boolean = false
  @State progress: number = 0
  @State timer: number = 0

  build() {
    Column({ space: 20 }) {
      // 加载状态按钮
      Button(this.isLoading ? '加载中...' : '开始加载')
        .width(200)
        .height(44)
        .backgroundColor(this.isLoading ? '#999' : '#007DFF')
        .fontColor(Color.White)
        .onClick(() => {
          if (!this.isLoading) {
            this.startLoading()
          }
        })
        .overlay(
          this.isLoading ? 
            Progress({ value: this.progress, total: 100 })
              .width(160)
              .color(Color.White) 
            : null
        )
      
      // 计时器按钮
      Button(`计时: ${this.timer}秒`)
        .width(150)
        .height(40)
        .backgroundColor('#34C759')
        .fontColor(Color.White)
        .onClick(() => {
          this.startTimer()
        })
      
      // 多状态按钮
      Button() {
        Row({ space: 8 }) {
          Image($r('app.media.icon_star'))
            .width(16)
            .height(16)
            .fillColor(Color.White)
          
          Text('多功能按钮')
            .fontColor(Color.White)
            .fontSize(14)
          
          Badge({ count: 3, position: BadgePosition.RightTop })
            .style({ color: Color.Red })
        }
      }
      .width(140)
      .height(36)
      .backgroundColor('#5856D6')
      
      // 按钮组
      ButtonGroup({ space: 10 }) {
        Button('选项1')
          .layoutWeight(1)
        Button('选项2')
          .layoutWeight(1)
        Button('选项3')
          .layoutWeight(1)
      }
      .width('100%')
      .height(40)
    }
    .width('100%')
    .padding(20)
  }

  startLoading() {
    this.isLoading = true
    this.progress = 0
    
    const interval = setInterval(() => {
      this.progress += 10
      if (this.progress >= 100) {
        clearInterval(interval)
        this.isLoading = false
        this.progress = 0
      }
    }, 200)
  }

  startTimer() {
    this.timer = 0
    const interval = setInterval(() => {
      this.timer++
      if (this.timer >= 10) {
        clearInterval(interval)
      }
    }, 1000)
  }
}

四、组件组合实战

4.1 综合应用示例

@Component
struct ComponentCombinationExample {
  @State newsList: any[] = [
    {
      id: 1,
      title: 'HarmonyOS 5.0发布新特性',
      content: '全面升级的分布式能力和性能优化',
      image: $r('app.media.news1'),
      time: '2小时前',
      read: false
    },
    {
      id: 2, 
      title: 'ArkUI 3.0框架详解',
      content: '声明式开发范式的最佳实践',
      image: $r('app.media.news2'),
      time: '5小时前',
      read: true
    }
  ]

  build() {
    List({ space: 10 }) {
      ForEach(this.newsList, (news: any) => {
        ListItem() {
          this.NewsItem(news)
        }
      })
    }
    .width('100%')
    .height('100%')
  }

  @Builder
  NewsItem(news: any) {
    Row({ space: 15 }) {
      // 新闻图片
      Image(news.image)
        .width(80)
        .height(60)
        .objectFit(ImageFit.Cover)
        .borderRadius(8)
      
      // 新闻内容
      Column({ space: 5 }) {
        Text(news.title)
          .fontSize(16)
          .fontWeight(FontWeight.Bold)
          .fontColor(news.read ? '#666' : Color.Black)
          .maxLines(1)
          .textOverflow({ overflow: TextOverflow.Ellipsis })
        
        Text(news.content)
          .fontSize(14)
          .fontColor('#666')
          .maxLines(2)
          .textOverflow({ overflow: TextOverflow.Ellipsis })
        
        Row() {
          Text(news.time)
            .fontSize(12)
            .fontColor('#999')
          
          if (!news.read) {
            Badge({ count: 1, position: BadgePosition.Right })
              .style({ color: Color.Red })
          }
        }
        .width('100%')
        .justifyContent(FlexAlign.SpaceBetween)
      }
      .layoutWeight(1)
      .alignItems(HorizontalAlign.Start)
      
      // 操作按钮
      Button('阅读')
        .width(60)
        .height(30)
        .fontSize(12)
        .backgroundColor('#007DFF')
        .fontColor(Color.White)
    }
    .width('100%')
    .padding(15)
    .backgroundColor(Color.White)
    .onClick(() => {
      news.read = true
    })
  }
}

总结

通过本文的深入学习,你已经掌握了HarmonyOS三大基础组件的完整用法:

  1. Text组件:文本显示、样式装饰、富文本、选择复制等高级特性
  2. Image组件:多种图片来源、样式效果、加载控制、缓存优化
  3. Button组件:多种按钮类型、状态管理、交互效果、高级功能

这些基础组件是构建复杂UI界面的基石,熟练掌握它们将为后续的布局学习和项目开发打下坚实基础。

需要参加鸿蒙认证的请点击 鸿蒙认证链接

posted @ 2025-10-30 10:54  ifeng918  阅读(10)  评论(0)    收藏  举报