鸿蒙 Next 数据量环形图标 Gauge 介绍
作者:auhgnixgnahz
- 2025-06-25 北京
本文字数:3159 字
阅读完需:约 10 分钟
当我们需要环形展示数据进度,但是又不想使用一个完整的圆环时,Progress 组件就不能满足我们的需求,例如汽车的速度表盘,这时我们就需要用引入 Gauge 组件,他可以满足环形进度展示的同时,设置起始角度,达到不封闭环形的数据展示。
看一下简单的实现效果:
使用介绍:
1.Gauge 使用时必须设置 Gauge(options:{value: number, min?: number, max?: number}),其中,最小值默认 0,最大值默认 100
2.Gauge 支持包含一个子组件,子组件的内容区为圆环外圆相切的矩形,如同大正方形区域,可以绘制表盘刻度,指针实现汽车表盘功能。
3.可以通过设置 startAngle、endAngle,改变初始值角度
4.description 设置内容区,如同小矩形区域,可以根据需求填充内容
5.背景色分段渐变环最大显示段数为 9 段
源码:
@Entry@ComponentV2struct GaugeTest { @Local value: number = 10 //当前数据值 @Local min: number = 0 //当前数据段最小值 @Local max: number = 200 //当前数据段最大值 @Local startAngle: number = 0 //起始角度位置 @Local endAngle: number = 360 //终止角度位置 @Local strokeWidth: number = 4 //环形厚度 @Local colors: ResourceColor | LinearGradient | Array<[ResourceColor | LinearGradient, number]> = '#a5d61d' private settings: RenderingContextSettings = new RenderingContextSettings(true); private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings); @Local centerX:number=0 @Local centerY:number=0 @Builder descriptionBuilder() { Stack() { Text('内容区') } .width('100%') .height("100%") .border({ width: 1 }) }
build() { Column({ space: 10 }) { Gauge({ value: this.value, min: this.min, max: this.max }) { Stack(){ Text('可以放一个子组件,子组件内容区黑色边框内').width('30%') Canvas(this.context) .width('100%') .height('100%') .onReady(() => { this.context.strokeStyle = '#0000ff'; this.context.lineWidth = 2; this.context.moveTo(this.centerX, this.centerY); this.context.lineTo(this.centerX, this.strokeWidth); this.context.stroke(); }) .rotate({ centerX:this.centerX,centerY:this.centerY,angle:this.cacleAngle() }) .animation({duration:300,iterations:1}) } .onSizeChange((oldValue: SizeOptions, newValue: SizeOptions) => { this.centerX=(newValue.width as number)/2 this.centerY=(newValue.height as number)/2-this.strokeWidth }) .width('100%') .height("100%") .border({ width: 1 }) } .width(300) .height(300) .startAngle(this.startAngle) .endAngle(this.endAngle) .colors(this.colors) .strokeWidth(this.strokeWidth) .description(this.descriptionBuilder) .indicator({ //指针样式 icon:$r('app.media.svg_triangle')
}) Column(){ Text('定制Gauge内容区') Gauge({ value: this.value, min: this.min, max: this.max }) .contentModifier(new MyGaugeStyle()) } Row({ space: 10 }) { Column() { Text("最小值") Counter() { Text(this.min.toString()) } .onInc(() => { this.min += 10; }) .onDec(() => { this.min -= 10; }) } Column() { Text("当前值") Counter() { Text(this.value.toString()) } .onInc(() => { if (this.value<this.max) { this.value+=10 } }) .onDec(() => { if (this.value > this.min) { this.value-= 10; } }) } Column() { Text("最大值") Counter() { Text(this.max.toString()) } .onInc(() => { this.max += 10; }) .onDec(() => { this.max -= 10; }) } } Row({ space: 10 }) { Column() { Text("起始角度") Counter() { Text(this.startAngle.toString()) } .onInc(() => { this.startAngle+= 10 }) .onDec(() => { if (this.startAngle > 0) { this.startAngle-= 10; } }) } Column() { Text("终止角度") Counter() { Text(this.endAngle.toString()) } .onInc(() => { this.endAngle += 10; }) .onDec(() => { this.endAngle -= 10; }) } Column() { Text("环形厚度") Counter() { Text(this.strokeWidth.toString()) } .onInc(() => { this.strokeWidth ++; }) .onDec(() => { if (this.strokeWidth > 0) { this.strokeWidth--; } }) } }
Row({ space: 10 }){ Button('纯色').onClick(()=>{ this.colors = '#a5d61d' }) Button('单渐变').onClick(()=>{ this.colors=new LinearGradient([{ color: "#dbefa5", offset: 0 }, { color: "#a5d61d", offset: 1 }]) }) Button('分段渐变').onClick(()=>{ this.colors=[ [new LinearGradient([{ color: "#dbefa5", offset: 0 }, { color: "#a5d61d", offset: 1 }]), 5], [new LinearGradient([{ color: "#fceb99", offset: 0 }, { color: "#f7ce00", offset: 1 }]), 3], [new LinearGradient([{ color: "#f8c5a6", offset: 0 }, { color: "#ed6f21", offset: 1 }]), 2] ] }) } } .width('100%') .alignItems(HorizontalAlign.Center) }
cacleAngle():number{ let offsetAngle = Math.abs((360-this.startAngle)-(360-this.endAngle)) if (offsetAngle==360) { offsetAngle=0 }
return (this.value*(360-offsetAngle)/this.max)+this.startAngle }}@Builderfunction buildGauge(config: GaugeConfiguration) { Column() { Progress({ value: config.value, total: config.max, type: ProgressType.Linear }) .color("#a5d61d") .width(200) } .width("100%") .padding(10) .alignItems(HorizontalAlign.Center)}class MyGaugeStyle implements ContentModifier<gaugeconfiguration> {
constructor() { }
applyContent(): WrappedBuilder<[GaugeConfiguration]> { return wrapBuilder(buildGauge) }}</gaugeconfiguration></this.max) {
复制代码
划线
评论
复制
发布于: 刚刚阅读数: 2
版权声明: 本文为 InfoQ 作者【auhgnixgnahz】的原创文章。
原文链接:【http://xie.infoq.cn/article/44ac0b8ea67d3193beff1b82e】。文章转载请联系作者。
auhgnixgnahz
关注
还未添加个人签名 2018-07-10 加入
欢迎关注:HarmonyOS开发笔记









评论