ArkUI Progress 组件详解与使用指南

Progress 是 ArkUI 中用于显示任务进度的组件,适用于文件上传、下载、操作执行等需要展示进度的场景。以下是 Progress 组件的详细介绍和使用方法。

基本介绍

Progress 组件特点:

  • 支持线性进度条和环形进度条两种样式
  • 可自定义颜色、宽度、背景等样式属性
  • 提供确定进度和不确定进度两种模式
  • 支持动态更新进度值

基本使用

1. 线性进度条

@Entry
@Component
struct LinearProgressExample {
  @State progressValue: number = 30 // 进度值(0-100)

  build() {
    Column({ space: 20 }) {
      // 基础线性进度条
      Progress({ value: this.progressValue, total: 100, type: ProgressType.Linear })
        .width('80%')
      
      // 带文本显示的进度条
      Row() {
        Progress({ value: this.progressValue, total: 100, type: ProgressType.Linear })
          .width('70%')
        Text(`${this.progressValue}%`)
          .margin({ left: 10 })
      }
      .width('80%')
      
      // 控制进度按钮
      Button('增加进度')
        .onClick(() => {
          if (this.progressValue < 100) {
            this.progressValue += 10
          }
        })
    }
    .width('100%')
    .height('100%')
    .justifyContent(FlexAlign.Center)
    .alignItems(HorizontalAlign.Center)
  }
}

2. 环形进度条

@Entry
@Component
struct CircularProgressExample {
  @State progressValue: number = 45

  build() {
    Column({ space: 20 }) {
      // 基础环形进度条
      Progress({ value: this.progressValue, total: 100, type: ProgressType.Ring })
        .width(100)
        .height(100)
      
      // 自定义样式的环形进度条
      Stack() {
        Progress({ value: this.progressValue, total: 100, type: ProgressType.Ring })
          .width(120)
          .height(120)
          .style({ strokeWidth: 10, scaleCount: 60 })
        
        Text(`${this.progressValue}%`)
          .fontSize(18)
      }
      
      Slider({ 
        value: this.progressValue, 
        min: 0, 
        max: 100,
        style: SliderStyle.OutSet
      })
      .onChange((value: number) => {
        this.progressValue = value
      })
      .width('80%')
    }
    .width('100%')
    .height('100%')
    .justifyContent(FlexAlign.Center)
    .alignItems(HorizontalAlign.Center)
  }
}

核心功能

1. 进度条类型

// 线性进度条
Progress({ type: ProgressType.Linear })

// 环形进度条
Progress({ type: ProgressType.Ring })

2. 不确定进度模式

// 不确定进度的加载指示器
Progress()
  .width(100)
  .height(100)
  .color(Color.Blue)

3. 样式自定义

Progress({ value: 50, total: 100 })
  .width('80%')
  .height(10) // 线性进度条高度
  .color('#FF0000') // 进度条颜色
  .backgroundColor('#EEEEEE') // 背景色
  .borderRadius(5) // 圆角

高级功能

1. 动态进度更新

@Entry
@Component
struct DynamicProgressExample {
  @State progressValue: number = 0
  private timer: number | null = null

  aboutToAppear() {
    this.startProgress()
  }

  aboutToDisappear() {
    this.stopProgress()
  }

  startProgress() {
    this.timer = setInterval(() => {
      if (this.progressValue >= 100) {
        this.progressValue = 0
      } else {
        this.progressValue += 2
      }
    }, 100)
  }

  stopProgress() {
    if (this.timer) {
      clearInterval(this.timer)
      this.timer = null
    }
  }

  build() {
    Column({ space: 20 }) {
      Progress({ value: this.progressValue, total: 100 })
        .width('80%')
      
      Button(this.timer ? '停止' : '开始')
        .onClick(() => {
          if (this.timer) {
            this.stopProgress()
          } else {
            this.startProgress()
          }
        })
    }
    .width('100%')
    .height('100%')
    .justifyContent(FlexAlign.Center)
    .alignItems(HorizontalAlign.Center)
  }
}

2. 分段进度条

@Entry
@Component
struct SegmentedProgressExample {
  @State progress1: number = 30
  @State progress2: number = 20
  @State progress3: number = 15

  build() {
    Column({ space: 10 }) {
      // 分段进度条
      Row() {
        Progress({ value: this.progress1, total: 100 })
          .width(`${this.progress1}%`)
          .height(20)
          .backgroundColor('#FF6A00')
        
        Progress({ value: this.progress2, total: 100 })
          .width(`${this.progress2}%`)
          .height(20)
          .backgroundColor('#00BFFF')
        
        Progress({ value: this.progress3, total: 100 })
          .width(`${this.progress3}%`)
          .height(20)
          .backgroundColor('#7CCD7C')
      }
      .width('80%')
      .borderRadius(10)
      .clip(true) // 裁剪超出部分
      
      // 图例说明
      Row({ space: 20 }) {
        Row() {
          Circle().width(10).height(10).fill('#FF6A00')
          Text('第一部分').margin({ left: 5 })
        }
        Row() {
          Circle().width(10).height(10).fill('#00BFFF')
          Text('第二部分').margin({ left: 5 })
        }
        Row() {
          Circle().width(10).height(10).fill('#7CCD7C')
          Text('第三部分').margin({ left: 5 })
        }
      }
      .margin({ top: 10 })
    }
    .width('100%')
    .height('100%')
    .justifyContent(FlexAlign.Center)
    .alignItems(HorizontalAlign.Center)
  }
}

3. 复杂环形进度条

@Entry
@Component
struct FancyCircularProgress {
  @State progressValue: number = 75

  build() {
    Stack() {
      // 背景圆环
      Progress({ value: 100, total: 100, type: ProgressType.Ring })
        .width(150)
        .height(150)
        .style({ 
          strokeWidth: 10,
          scaleCount: 0,
          strokeColor: '#EEEEEE'
        })
      
      // 进度圆环
      Progress({ value: this.progressValue, total: 100, type: ProgressType.Ring })
        .width(150)
        .height(150)
        .style({ 
          strokeWidth: 10,
          scaleCount: 0,
          strokeColor: {
            gradient: {
              angle: 90,
              colors: ['#FF6A00', '#FF0000']
            }
          }
        })
      
      // 内圆
      Circle()
        .width(130)
        .height(130)
        .fill('#FFFFFF')
      
      // 进度文本
      Column() {
        Text(`${this.progressValue}%`)
          .fontSize(24)
          .fontWeight(FontWeight.Bold)
        Text('已完成')
          .fontSize(12)
          .margin({ top: 5 })
      }
    }
    .onClick(() => {
      animateTo({
        duration: 500,
        curve: Curve.EaseInOut
      }, () => {
        this.progressValue = this.progressValue >= 100 ? 0 : this.progressValue + 25
      })
    })
  }
}

最佳实践

  1. 进度反馈

    • 长时间操作必须显示进度
    • 超过5秒的操作建议显示剩余时间估计
  2. 样式设计

    • 重要操作使用醒目颜色
    • 保持进度条宽度/高度适合所在位置
  3. 交互设计

    • 可取消的操作应提供取消按钮
    • 完成/失败时提供状态变化反馈
  4. 性能优化

    • 避免频繁更新进度(如每1%更新一次)
    • 复杂动画使用animateTo优化
  5. 无障碍设计

    • 为进度条添加accessibilityLabel
    • 确保颜色对比度符合标准

实际应用示例

1. 文件上传进度

@Entry
@Component
struct FileUploader {
  @State uploadProgress: number = 0
  @State isUploading: boolean = false
  @State fileName: string = ''

  simulateUpload() {
    this.isUploading = true
    this.uploadProgress = 0
    const interval = setInterval(() => {
      if (this.uploadProgress >= 100) {
        clearInterval(interval)
        this.isUploading = false
      } else {
        this.uploadProgress += Math.random() * 10
        if (this.uploadProgress > 100) {
          this.uploadProgress = 100
        }
      }
    }, 500)
  }

  build() {
    Column({ space: 20 }) {
      if (this.fileName) {
        Text(`正在上传: ${this.fileName}`)
      }
      
      if (this.isUploading) {
        Column({ space: 10 }) {
          Progress({ value: this.uploadProgress, total: 100 })
            .width('80%')
          
          Row() {
            Text(`${this.uploadProgress.toFixed(0)}%`)
              .fontSize(16)
            Blank()
            Button('取消')
              .onClick(() => {
                this.isUploading = false
                this.uploadProgress = 0
              })
          }
          .width('80%')
        }
      } else {
        Button('选择文件')
          .onClick(() => {
            // 模拟文件选择
            this.fileName = 'document.pdf'
            this.simulateUpload()
          })
      }
    }
    .width('100%')
    .height('100%')
    .justifyContent(FlexAlign.Center)
    .alignItems(HorizontalAlign.Center)
  }
}

2. 健康数据环形图

@Entry
@Component
struct HealthProgress {
  @State steps: number = 7500
  private targetSteps: number = 10000

  build() {
    Column({ space: 20 }) {
      Stack() {
        // 背景圆环
        Progress({ value: 100, total: 100, type: ProgressType.Ring })
          .width(200)
          .height(200)
          .style({ 
            strokeWidth: 15,
            scaleCount: 0,
            strokeColor: '#F0F0F0'
          })
        
        // 进度圆环
        Progress({ 
          value: this.steps, 
          total: this.targetSteps, 
          type: ProgressType.Ring 
        })
          .width(200)
          .height(200)
          .style({ 
            strokeWidth: 15,
            scaleCount: 0,
            strokeColor: '#00BFFF'
          })
        
        Column() {
          Text(`${this.steps}`)
            .fontSize(32)
            .fontWeight(FontWeight.Bold)
          Text(`目标 ${this.targetSteps}`)
            .fontSize(14)
            .fontColor('#666666')
            .margin({ top: 5 })
        }
      }
      
      Text('今日步数')
        .fontSize(18)
      
      Slider({
        value: this.steps,
        min: 0,
        max: this.targetSteps
      })
      .onChange((value: number) => {
        this.steps = Math.floor(value)
      })
      .width('80%')
      .margin({ top: 30 })
    }
    .width('100%')
    .height('100%')
    .justifyContent(FlexAlign.Center)
    .alignItems(HorizontalAlign.Center)
  }
}

通过合理使用 Progress 组件,可以有效展示任务进度,提升用户体验。根据具体场景选择合适的样式和交互方式,使进度显示既美观又实用。

Logo

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

更多推荐