HarmonyOS 鸿蒙Next基于Progress组件的进度条

发布于 1周前 作者 sinazl 来自 鸿蒙OS

HarmonyOS 鸿蒙Next基于Progress组件的进度条
<markdown _ngcontent-glg-c237="" class="markdownPreContainer">

场景一:反向进度条

效果

倒计时样式的进度条

方案

注意:这个Progress组件最常见的是和通用属性rotate一起使用,除了上图这种逆向倒计时,还有那种类似于温度计(从下到上加载)的效果,全都是利用rotate。

ArkUI中组件的方向轴示意图:

一般而言,我们的Progress组件都是顺时针从0→100加载的。

1.Progress组件从100→0加载。

2.把这个圆形Progress按照y轴旋转180°,也就是想象一枚硬币翻转一面的样子。

核心代码

[@Component](/user/Component)
export struct ReverseProgress {
  [@State](/user/State) progressValue: number = 100
  [@State](/user/State) animationId: number | null = null
  build() {
    NavDestination() {
      Column({ space: 15 }) {
        Progress({ value: 0, total: 100, type: ProgressType.Ring })
          .color('#A97CF9')
          .value(this.progressValue)
          .width(100)
          .style({
            strokeWidth: 10,
            scaleCount: 20,
            scaleWidth: 5,
            enableSmoothEffect: true
          })
          .backgroundColor(Color.White)
          .rotate({
            x: 0,
            y: 1,
            z: 0,
            centerX: '50%',
            centerY: '50%',
            angle: 180
          })
        Button('开始动画')
          .onClick(() => {
            if (this.animationId === null) {
              this.animationId = setInterval(() => {
                this.progressValue--
                if (this.progressValue == 0) {
                  this.progressValue = 100
                }
              }, 10)
            }
            console.log(this.animationId.toString())
          })
        Button('结束动画').onClick(() => {
          clearInterval(this.animationId)
          this.animationId = null
          this.progressValue = 100
        })
      }.width('100%').padding({ top: 5 }).backgroundColor(Color.Red)
    }

} } <button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 4px; right: 8px; font-size: 14px;">复制</button>

场景二:自定义电池电量的显示

效果

方案

clip(value: boolean | CircleAttribute | EllipseAttribute | PathAttribute | RectAttribute)

按指定的形状对当前组件进行裁剪。

卡片能力: 从API version 9开始,该接口支持在ArkTS卡片中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

参数:

参数名

类型

必填

说明

value

boolean | CircleAttribute | EllipseAttribute | PathAttribute | RectAttribute

参数为相应类型的组件,按指定的形状对当前组件进行裁剪;参数为boolean类型时,设置是否按照父容器边缘轮廓进行裁剪。默认值:false

在使用Progress的时候要注意像如上场景中的电池型的进度条,中间的进度条是横线,而我们的这个组件Linear类型中进度条默认是带有弧度的,若要改变其边角半径就要使用clip属性,而大多数开发者往往会忽略这一点,注意使用Progress组件的时候一定要使用clip属性。

核心代码

[@Component](/user/Component)
export struct ClipProgress {
  build() {
    NavDestination() {
      Column({ space: 15 }) {
        Text('Linear Progress').fontSize(9).fontColor(0xCCCCCC).width('90%')
        Progress({ value: 20, total: 100, type: ProgressType.Linear })
          .width(200)
          .backgroundColor('#DDDDDD')
          .style({ strokeRadius: 0, strokeWidth: 100, })
          .color('#B1B1B1')
          .borderColor('#00000000')
          .borderRadius(20)
          .clip(true)
      }.width('100%').height('100%').margin({ top: 30 }).backgroundColor('#F6F6F6')
    }
  }
}
<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 4px; right: 8px; font-size: 14px;">复制</button>

场景三:扇形圆弧进度条

效果

方案

场景一和场景二是可以用progress组件配合其他属性来实现,但是有的不行,例如互联网运营商的app中的流量码表,这种建议不使用progress,使用canvas来自己绘制,具体实现代码如下。

核心代码

[@Component](/user/Component)
export struct WidgetsProgress {
  private settings: RenderingContextSettings = new RenderingContextSettings(true)
  private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings)
  private offCanvas: OffscreenCanvas = new OffscreenCanvas(600, 600)
  [@State](/user/State) [@Watch](/user/Watch)('onCountUpdated') radianTest: number = 0
  [@State](/user/State) color: string = '#ff8c909b'

onCountUpdated(): void { this.canvasTest() }

canvasTest = (): void => { let offContext = this.offCanvas.getContext(‘2d’, this.settings) offContext.lineCap = ‘round’ offContext.lineWidth = 8 offContext.beginPath() offContext.arc( 100, 75, 50, (225 - 90) * Math.PI / 180, (135 - 90) * Math.PI / 180 ) offContext.strokeStyle = ‘#ff8c909b’ offContext.stroke()

offContext.beginPath()
offContext.arc(
  <span class="hljs-number"><span class="hljs-number">100</span></span>,
  <span class="hljs-number"><span class="hljs-number">75</span></span>,
  <span class="hljs-number"><span class="hljs-number">50</span></span>,
  (<span class="hljs-number"><span class="hljs-number">225</span></span> - <span class="hljs-number"><span class="hljs-number">90</span></span>) * (Math.PI / <span class="hljs-number"><span class="hljs-number">180</span></span>),
  <span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.radianTest === <span class="hljs-number"><span class="hljs-number">0</span></span> ? (<span class="hljs-number"><span class="hljs-number">135</span></span> - <span class="hljs-number"><span class="hljs-number">90</span></span>) * (Math.PI / <span class="hljs-number"><span class="hljs-number">180</span></span>) : (<span class="hljs-number"><span class="hljs-number">135</span></span> - <span class="hljs-number"><span class="hljs-number">270</span></span> * (<span class="hljs-number"><span class="hljs-number">1</span></span> - <span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.radianTest) - <span class="hljs-number"><span class="hljs-number">90</span></span>) * (Math.PI / <span class="hljs-number"><span class="hljs-number">180</span></span>),
)
offContext.strokeStyle = <span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.color
offContext.stroke()
<span class="hljs-reserved"><span class="hljs-reserved">let</span></span> image = <span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.offCanvas.transferToImageBitmap()
<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.context.transferFromImageBitmap(image)

}

build() { NavDestination() { Column() { Canvas(this.context) .width(‘100%’) .height(‘100%’) .backgroundColor(’#ffff00’) .onReady( this.canvasTest )

    Button(<span class="hljs-string"><span class="hljs-string">'test'</span></span>)
      .onClick<span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params">(() =&gt; {
        </span></span><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-params"><span class="hljs-keyword">this</span></span></span></span><span class="hljs-function"><span class="hljs-params">.color = </span></span><span class="hljs-string"><span class="hljs-function"><span class="hljs-params"><span class="hljs-string">'#ff144cd2'</span></span></span></span><span class="hljs-function"><span class="hljs-params">
        </span></span><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-params"><span class="hljs-keyword">this</span></span></span></span><span class="hljs-function"><span class="hljs-params">.radianTest = Number(</span></span><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-params"><span class="hljs-keyword">this</span></span></span></span><span class="hljs-function"><span class="hljs-params">.radianTest + </span></span><span class="hljs-number"><span class="hljs-function"><span class="hljs-params"><span class="hljs-number">0.01</span></span></span></span><span class="hljs-function"><span class="hljs-params">)
        </span></span><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-params"><span class="hljs-keyword">if</span></span></span></span><span class="hljs-function"><span class="hljs-params"> (</span></span><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-params"><span class="hljs-keyword">this</span></span></span></span><span class="hljs-function"><span class="hljs-params">.radianTest &gt; </span></span><span class="hljs-number"><span class="hljs-function"><span class="hljs-params"><span class="hljs-number">1</span></span></span></span><span class="hljs-function"><span class="hljs-params">) {
          </span></span><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-params"><span class="hljs-keyword">this</span></span></span></span><span class="hljs-function"><span class="hljs-params">.radianTest = </span></span><span class="hljs-number"><span class="hljs-function"><span class="hljs-params"><span class="hljs-number">0</span></span></span></span><span class="hljs-function"><span class="hljs-params">
        }
      })</span></span></span><span class="hljs-function">
  }
  .</span><span class="hljs-title"><span class="hljs-function"><span class="hljs-title">width</span></span></span><span class="hljs-params"><span class="hljs-function"><span class="hljs-params">(</span></span><span class="hljs-string"><span class="hljs-function"><span class="hljs-params"><span class="hljs-string">'100%'</span></span></span></span><span class="hljs-function"><span class="hljs-params">)</span></span></span><span class="hljs-function">
  .</span><span class="hljs-title"><span class="hljs-function"><span class="hljs-title">height</span></span></span><span class="hljs-params"><span class="hljs-function"><span class="hljs-params">(</span></span><span class="hljs-number"><span class="hljs-function"><span class="hljs-params"><span class="hljs-number">500</span></span></span></span><span class="hljs-function"><span class="hljs-params">)</span></span></span><span class="hljs-function">
}

} } <button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 4px; right: 8px; font-size: 14px;">复制</button>

常见问题

  1. progress有没有设置速度的属性?

    暂时没有。

  2. progress为什么有些类型设置渐变色生效有些不生效?

    目前progress组件只支持ring类型的渐变色,其它类型暂不支持。

</markdown>
1 回复

HarmonyOS 鸿蒙Next中的Progress组件用于展示操作进度,支持多种样式,包括线性(Linear)、环形(Ring)、带刻度环形(ScaleRing)、圆形(Eclipse)和胶囊形(Capsule)。通过设置value(当前进度值)和total(总进度值)属性来定义进度条的当前状态。Progress组件还支持动态更新进度,适用于多种场景。如果问题依旧没法解决请加我微信,我的微信是itying888。

回到顶部