#跟着若城学鸿蒙# 自定义圆环(Ring)—组合方式实现
·
在 UI 设计中,圆环(Ring)是一种常见的视觉元素,用以展示进度、刻度或装饰效果。通过组合现有的 Circle
组件,我们可以轻松地实现一个可定制的圆环控件,并支持外部传参来设置半径、环宽、环色及填充色。下面将分步介绍如何创建这样一个自定义组件。
1. 创建 Ring 组件骨架
首先,定义一个导出的组件 Ring
,让系统识别它并生成相应的生命周期钩子。
@Component export
struct Ring {
build() {
// 待填充:组合布局
}
}
@Component
:标记这是一个组件,必须实现build()
。export
:允许在其他模块中import
并使用。struct Ring
:组件本质上是一个结构体。
2. 组合两个 Circle 实现基础圆环
通过 Stack
将两个圆堆叠:
- 底层大圆充满父布局,作为环的外径。
- 顶层小圆居中显示,绘制出“镂空”效果。
@Component export
struct Ring {
build() {
Stack({ alignContent: Alignment.Center }) {
// 外圆:环的外边界
Circle()
.width('100%')
.height('100%')
// 内圆:环的镂空部分
Circle()
.width(83)
.height(83)
.fill(Color.White)
}
.width(90)
.height(90)
}
}
此时虽然能看到一个圆环,但它的大小和颜色固定,无法外部定制。
3. 定义可配置属性:RingAttribute
为了让 Ring
支持动态配置,我们需要先定义一个属性类 RingAttribute
,提前声明所有可传参数及其默认值,并提供一个静态方法 filter
来保证合理性:
class RingAttribute {
radius: number = 45; // 半径,默认45
width: number = 5; // 环宽,默认5
color: Color | number | string | Resource = '#000000'; // 环色,默认黑色
solid: Color | number | string | Resource = '#ffffff'; // 填充色,默认白色
/** 参数过滤,缺省时补全默认值 */
public static filter(attr: RingAttribute): RingAttribute {
if (!attr) {
return new RingAttribute();
}
const def = new RingAttribute();
attr.radius ??= def.radius;
attr.width ??= def.width;
attr.color ??= def.color;
attr.solid ??= def.solid;
return attr;
}
}
- **
radius
**:外圆半径。 - **
width
**:环的厚度。 - **
color
**:环的边框颜色。 - **
solid
**:环内部的填充色。
4. 在 Ring 组件中使用属性并做校验
引入上述属性类后,需在组件的 aboutToAppear()
钩子中先行过滤参数,再在 build()
中根据其值动态绘制:
@Component export
struct Ring {
public ringAttribute: RingAttribute = null;
/** 在 build 前校验并补全参数 */
private aboutToAppear() {
this.ringAttribute = RingAttribute.filter(this.ringAttribute);
}
build() {
const r = this.ringAttribute.radius;
const w = this.ringAttribute.width;
Stack({ alignContent: Alignment.Center }) {
// 外圆:用 ringAttribute.color
Circle()
.width(r * 2)
.height(r * 2)
.strokeWidth(w)
.stroke(this.ringAttribute.color)
// 内圆:用 ringAttribute.solid
Circle()
.width(r * 2 - w * 2)
.height(r * 2 - w * 2)
.fill(this.ringAttribute.solid)
}
.width(r * 2)
.height(r * 2)
}
}
- 在
aboutToAppear()
中调用filter
,确保所有属性都有有效值。 build()
方法根据radius
、width
等动态设置Circle
的尺寸和样式。
5. 使用 Ring 并传递参数
完成组件封装后,便可在页面中像使用系统组件一样引用,并将配置项通过构造参数传入:
import { Ring } from '../common/widgets/ring_widget.ets';
@Entry @Component
struct ComponentTest {
build() {
Column({ space: 10 }) {
Row({ space: 5 }) {
Ring() // 默认样式
Ring({ ringAttribute: { // 自定义样式
radius: 40,
width: 8,
color: Color.Green,
solid: '#aabbcc'
}})
Ring({ ringAttribute: { // 再一版自定义
radius: 50,
width: 10,
color: Color.Red,
solid: Color.Pink
}})
}
}
.padding(10)
.width('100%')
.height('100%')
}
}
运行效果便是三个不同大小、颜色和环宽的圆环组件并排展示。
小结
- 组合现有控件:利用
Circle
和Stack
便可快速搭建圆环。 - 属性驱动:通过自定义的
RingAttribute
,支持外部传参并在生命周期前校验。 - 可复用性:组件以标准方式导出后,可在任意页面直接使用并定制。
掌握上述思路后,你可以轻松地基于系统组件组合出各种可定制的图形控件——不仅限于圆环,还可以是刻度盘、环形进度或装饰性边框。下篇文章将进一步介绍如何用 Canvas 或 MiniCanvas 自绘来实现同样的圆环效果。
更多推荐
所有评论(0)