HarmonyOS鸿蒙Next中如何实现垂直刻度线,根据数值改变来逐个变色的进度效果

HarmonyOS鸿蒙Next中如何实现垂直刻度线,根据数值改变来逐个变色的进度效果 效果图是这样

随着进度数值变化,进度条逐步改为蓝色。 看了一圈官方文档,感觉也没有合适的组件啊。感谢感谢感谢!


更多关于HarmonyOS鸿蒙Next中如何实现垂直刻度线,根据数值改变来逐个变色的进度效果的实战教程也可以访问 https://www.itying.com/category-93-b0.html

5 回复

【背景知识】

  • 状态管理(V1): 自定义组件中的变量必须被装饰器装饰才可以成为状态变量,状态变量的改变会引起UI的渲染刷新。其中@State@Prop@Link@Provide和@Consume装饰器都只能观察第一层的变化;@Observed/@ObjectLink配套使用是用于嵌套场景的观察,主要是为了弥补上述装饰器仅能观察一层的能力限制,比如二维数组,或者数组项class,或者class的属性是class。
  • 状态管理(V2): 提供了一套全新的装饰器,@ObservedV2装饰器装饰class,使得被装饰的类具有深度监听的能力,@ObservedV2@Trace配合使用可以使类中的属性具有深度观测的能力,尤其对于二维数组使用V2版本更容易实现数据的监听。

【解决方案】

使用 List 实现,ListItem的组件作为刻度。@State绑定一个变量,使用这个变量控制刻度的颜色。

参考代码:

@Entry
@Component
struct Index {
  arr:number[] = [];
  maxValue:number = 80000;
  stepValue:number = 1000;
  [@State](/user/State) currValue:number = 8848;

  aboutToAppear(): void {
    for(let i=this.maxValue;i>0;i=i-this.stepValue) {
      this.arr.push(i)
    }
  }

  build() {
    Column() {
      List({space:4}) {
        ListItem() {
          Text(`余${this.currValue}ml`)
        }
        ForEach(this.arr,(item:number)=>{
          ListItem(){
            Column()
              .width('100%')
              .height(4)
              .backgroundColor(this.currValue>=item ? Color.Blue : Color.Gray)
              .borderRadius(4)
          }.width(item%(5*this.stepValue)===0 ? 50 : 36)
        })
      }.height('90%')
      Row() {
        Button('加1000').onClick(()=>{
          if (this.currValue <= this.maxValue - 1000) {
            this.currValue += 1000;
          } else {
            this.currValue = this.maxValue;
          }

        })
        Button('减1000').onClick(()=>{
          if (this.currValue >= 1000) {
            this.currValue -= 1000;
          } else {
            this.currValue = 0
          }
        })
      }
    }
    .height('100%')
    .width('100%')
  }
}

更多关于HarmonyOS鸿蒙Next中如何实现垂直刻度线,根据数值改变来逐个变色的进度效果的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


1、简单点,使用 List 实现,把 进度值 当做ListItem里的组件,只是宽度和颜色不一样,实现不难。

2、使用 Canvas 去画,熟悉相关api的话,就是多画些圆角矩形, 也比较简单 。

感谢建议,还想请问一下改变颜色这个怎么实现呢,

在HarmonyOS Next中,可通过Canvas组件绘制垂直刻度线。使用CanvasRenderingContext2DmoveTolineTo方法绘制垂直线条。通过for循环控制刻度数量与位置。根据数值变化,在绘制时动态判断当前刻度索引与数值比例,使用strokeStyle属性设置不同颜色(如条件判断后分别赋予不同色值),实现逐个变色效果。

在HarmonyOS Next中实现垂直刻度线进度条,可以通过自定义Canvas绘制完成。以下是核心实现思路和代码示例:

1. 绘制垂直刻度线

使用CanvasRenderingContext2DstrokeRectmoveTo/lineTo方法绘制垂直线条,通过循环控制刻度数量和间距。

// 示例:绘制基础刻度线
private drawScale(context: CanvasRenderingContext2D, total: number) {
  const scaleWidth = 2;
  const scaleSpacing = 10;
  const startX = 50;
  
  for (let i = 0; i <= total; i++) {
    const yPos = i * scaleSpacing;
    context.beginPath();
    context.moveTo(startX, yPos);
    context.lineTo(startX + 20, yPos); // 刻度长度20
    context.lineWidth = scaleWidth;
    context.stroke();
  }
}

2. 动态变色逻辑

根据进度值计算需要变色的刻度数量,在绘制时动态设置颜色:

private drawProgress(context: CanvasRenderingContext2D, current: number, total: number) {
  const progressCount = Math.floor((current / 100) * total);
  
  for (let i = 0; i < total; i++) {
    context.strokeStyle = i < progressCount ? '#007DFF' : '#E5E5E5'; // 蓝色/灰色
    // 绘制单个刻度(代码略)
  }
}

3. 完整组件示例

@Component
struct VerticalProgressBar {
  @State currentProgress: number = 30;
  private totalScales: number = 20;

  build() {
    Column() {
      Canvas(this.onDraw)
        .width(100)
        .height(300)
      
      Button('增加进度')
        .onClick(() => {
          this.currentProgress = Math.min(this.currentProgress + 5, 100);
        })
    }
  }

  onDraw(context: CanvasRenderingContext2D) {
    const scaleCount = this.totalScales;
    const progressScales = (this.currentProgress / 100) * scaleCount;
    
    for (let i = 0; i < scaleCount; i++) {
      // 设置颜色
      context.strokeStyle = i < progressScales ? '#007DFF' : '#E5E5E5';
      context.lineWidth = 3;
      
      // 绘制垂直线段
      const yPos = i * 15;
      context.beginPath();
      context.moveTo(40, yPos);
      context.lineTo(60, yPos);
      context.stroke();
    }
  }
}

关键点说明:

  1. 刻度计算:通过(currentProgress / 100) * totalScales确定变色刻度数量
  2. 性能优化:建议使用@State管理进度值,仅触发必要重绘
  3. 样式调整:修改lineWidth控制线条粗细,调整间距参数适应不同高度

此方案完全基于ArkUI的Canvas能力,无需额外组件库。通过控制绘制逻辑中的颜色条件,即可实现动态变色效果。

回到顶部