#跟着若城学鸿蒙# HarmonyOS NEXT学习之Checkbox案例三:自定义复选框与禁用状态
·
在本篇案例中,我们将学习如何在HarmonyOS NEXT中创建自定义外观的复选框,以及如何处理复选框的禁用状态,为用户提供更丰富的交互体验。
案例目标
- 学习如何创建完全自定义外观的复选框
- 掌握复选框禁用状态的处理方法
- 实现带动画效果的复选框
- 了解不同状态下的样式切换
代码实现
1. 自定义外观复选框
以下是一个完全自定义外观的复选框实现,使用自定义图标替代默认的勾选标记:
@Entry
@Component
struct CustomCheckboxDemo {
@State isChecked1: boolean = false
@State isChecked2: boolean = false
@State isChecked3: boolean = false
build() {
Column({ space: 30 }) {
// 标题
Text('自定义外观复选框')
.fontSize(22)
.fontWeight(FontWeight.Bold)
.margin({ bottom: 20 })
// 自定义图标复选框
Row({ space: 10 }) {
// 使用自定义组件实现复选框
this.CustomIconCheckbox({
checked: $isChecked1,
icon: '❤️', // 心形图标
text: '收藏',
color: '#FF4081'
})
}
.width('100%')
.padding(10)
.backgroundColor('#F8F8F8')
.borderRadius(8)
// 星形评分复选框
Row({ space: 10 }) {
// 使用自定义组件实现复选框
this.CustomIconCheckbox({
checked: $isChecked2,
icon: '⭐', // 星形图标
text: '收藏到我的最爱',
color: '#FFC107'
})
}
.width('100%')
.padding(10)
.backgroundColor('#F8F8F8')
.borderRadius(8)
// 自定义形状复选框
Row({ space: 10 }) {
// 使用自定义组件实现复选框
this.CustomShapeCheckbox({
checked: $isChecked3,
text: '同意用户协议',
color: '#4CAF50'
})
}
.width('100%')
.padding(10)
.backgroundColor('#F8F8F8')
.borderRadius(8)
}
.width('100%')
.height('100%')
.padding(20)
}
@Builder
CustomIconCheckbox({checked, icon, text, color}: {checked: Observed<boolean>, icon: string, text: string, color: string}) {
Row({ space: 10 }) {
// 自定义复选框容器
Stack() {
// 背景
Rect()
.width(28)
.height(28)
.radius(6)
.fill(checked.get() ? color : '#FFFFFF')
.stroke(color)
.strokeWidth(2)
// 图标
if (checked.get()) {
Text(icon)
.fontSize(16)
.fontColor('#FFFFFF')
}
}
.width(28)
.height(28)
.onClick(() => {
checked.set(!checked.get())
})
// 文本
Text(text)
.fontSize(16)
}
.width('100%')
.alignItems(VerticalAlign.Center)
}
@Builder
CustomShapeCheckbox({checked, text, color}: {checked: Observed<boolean>, text: string, color: string}) {
Row({ space: 10 }) {
// 自定义复选框容器
Stack() {
// 背景 - 使用六边形
Polygon({
points: [
[14, 0], [28, 7],
[28, 21], [14, 28],
[0, 21], [0, 7]
]
})
.fill(checked.get() ? color : '#FFFFFF')
.stroke(color)
.strokeWidth(2)
// 勾选标记
if (checked.get()) {
Path()
.commands('M6 14 L12 20 L22 8')
.stroke('#FFFFFF')
.strokeWidth(2)
.strokeLineCap(LineCapStyle.Round)
.strokeLineJoin(LineJoinStyle.Round)
}
}
.width(28)
.height(28)
.onClick(() => {
checked.set(!checked.get())
})
// 文本
Text(text)
.fontSize(16)
}
.width('100%')
.alignItems(VerticalAlign.Center)
}
}
2. 禁用状态与动画效果
以下是一个实现禁用状态和动画效果的复选框示例:
@Entry
@Component
struct DisabledAndAnimatedCheckboxDemo {
@State isChecked1: boolean = false
@State isChecked2: boolean = true
@State isDisabled1: boolean = true
@State isDisabled2: boolean = true
@State isChecked3: boolean = false
build() {
Column({ space: 30 }) {
// 标题
Text('禁用状态与动画效果')
.fontSize(22)
.fontWeight(FontWeight.Bold)
.margin({ bottom: 20 })
// 禁用状态 - 未选中
Row({ space: 10 }) {
Checkbox()
.select(this.isChecked1)
.disabled(this.isDisabled1)
.onChange((value: boolean) => {
this.isChecked1 = value
})
Text(`禁用状态 - 未选中`)
.fontSize(16)
.opacity(this.isDisabled1 ? 0.5 : 1.0) // 文本也显示禁用效果
}
.width('100%')
.padding(10)
.backgroundColor('#F8F8F8')
.borderRadius(8)
// 禁用状态 - 已选中
Row({ space: 10 }) {
Checkbox()
.select(this.isChecked2)
.disabled(this.isDisabled2)
.onChange((value: boolean) => {
this.isChecked2 = value
})
Text(`禁用状态 - 已选中`)
.fontSize(16)
.opacity(this.isDisabled2 ? 0.5 : 1.0) // 文本也显示禁用效果
}
.width('100%')
.padding(10)
.backgroundColor('#F8F8F8')
.borderRadius(8)
// 切换禁用状态的按钮
Row({ space: 20 }) {
Button('启用/禁用复选框')
.onClick(() => {
this.isDisabled1 = !this.isDisabled1
this.isDisabled2 = !this.isDisabled2
})
}
.width('100%')
.justifyContent(FlexAlign.Center)
.margin({ bottom: 20 })
// 带动画效果的复选框
Text('带动画效果的复选框')
.fontSize(18)
.fontWeight(FontWeight.Medium)
.margin({ bottom: 10 })
Row({ space: 10 }) {
// 自定义动画复选框
this.AnimatedCheckbox({
checked: $isChecked3,
text: '带动画效果'
})
}
.width('100%')
.padding(10)
.backgroundColor('#F8F8F8')
.borderRadius(8)
}
.width('100%')
.height('100%')
.padding(20)
}
@Builder
AnimatedCheckbox({checked, text}: {checked: Observed<boolean>, text: string}) {
Row({ space: 10 }) {
// 自定义动画复选框
Stack() {
// 背景
Rect()
.width(28)
.height(28)
.radius(6)
.fill(checked.get() ? '#2196F3' : '#FFFFFF')
.stroke('#2196F3')
.strokeWidth(2)
.animation({
duration: 300, // 动画持续时间
curve: Curve.EaseOut, // 动画曲线
iterations: 1, // 动画重复次数
playMode: PlayMode.Normal // 动画播放模式
})
// 勾选标记
if (checked.get()) {
Path()
.commands('M6 14 L12 20 L22 8')
.stroke('#FFFFFF')
.strokeWidth(2)
.strokeLineCap(LineCapStyle.Round)
.strokeLineJoin(LineJoinStyle.Round)
.opacity(0)
.animation({
duration: 300,
curve: Curve.EaseOut,
delay: 150, // 延迟显示勾选标记
iterations: 1,
playMode: PlayMode.Normal,
onFinish: () => {}
})
.opacity(1) // 动画结束时的不透明度
}
}
.width(28)
.height(28)
.onClick(() => {
checked.set(!checked.get())
})
// 文本
Text(text)
.fontSize(16)
}
.width('100%')
.alignItems(VerticalAlign.Center)
}
}
关键点解析
1. 自定义外观复选框要点
- 自定义组件:使用
@Builder装饰器创建可复用的自定义复选框组件 - 状态管理:使用
Observed<boolean>类型参数传递和管理选中状态 - 自定义图标:使用文本、图形或图标替代默认的勾选标记
- 自定义形状:使用
Polygon或Path组件创建非矩形的复选框
2. 禁用状态与动画效果要点
- 禁用状态:使用
disabled属性设置复选框的禁用状态 - 视觉反馈:通过降低不透明度等方式提供禁用状态的视觉反馈
- 动画配置:使用
animation属性配置动画效果 - 动画时序:通过
delay属性控制动画的时序,实现连贯的动画效果
应用场景
- 品牌定制:根据应用的品牌风格定制复选框外观
- 游戏界面:在游戏中使用主题化的复选框增强用户体验
- 特殊交互:在需要特殊交互反馈的场景中使用动画效果
- 表单验证:在表单验证中使用禁用状态表示某些选项不可用
注意事项
- 自定义复选框时,确保保留基本的交互逻辑和视觉反馈
- 动画效果应适度,避免过于复杂的动画影响用户体验
- 禁用状态应有明确的视觉区分,让用户能够识别
- 自定义组件应考虑无障碍设计,确保所有用户都能正常使用
小结
通过本案例,我们学习了如何在HarmonyOS NEXT中创建自定义外观的复选框,以及如何处理复选框的禁用状态和动画效果。这些技巧可以帮助我们创建更具个性化和交互性的用户界面,提升用户体验。
在下一篇案例中,我们将学习如何在实际应用场景中综合运用Checkbox组件,实现更复杂的业务需求。
更多推荐



所有评论(0)