一、Checkbox
1.1 多选框
场景:Checkbox用于一种常用的用户界面元素,用于表示二进制选择状态,即“选中”或“未选中”。
2.2 参数CheckboxOptions说明
| 名称 | 类型 | 必填 | 描述 |
|---|---|---|---|
| name | string | 否 | 用于指定多选框名称。一般结合CheckboxGroup一起使用 |
| group | string | 否 | 用于指定多选框所属群组的名称(即所属CheckboxGroup的名称)。 |
2.3 常用属性
| 名称 | 参数类型 | 描述 |
|---|---|---|
| select | boolean | 设置多选框是否选中。 默认值:false 从API version 9开始,该接口支持在ArkTS卡片中使用。 从API version 10开始,该属性支持$$双向绑定变量。 |
| selectedColor | ResourceColor | 设置多选框选中状态颜色。 说明: 默认值:$r(‘sys.color.ohos_id_color_text_primary_activated’)。 异常值按照默认值处理。 从API version 9开始,该接口支持在ArkTS卡片中使用。 |
| unselectedColor | ResourceColor | 设置多选框非选中状态边框颜色。 |
| shape | CheckBoxShape | 设置CheckBox组件形状, 包括圆形和圆角方形。 说明: 默认值:CheckBoxShape.CIRCLE。 |
| .......... |
2.4. CheckboxGroup
如果要控制多个 Checkbox 的选中状态,可以通过CheckBoxGroup来实现
2.4.1. 基本使用
CheckboxGroup(options?: CheckboxGroupOptions)
参数说明(CheckboxGroupOptions)
| 名称 | 类型 | 必填 | 说明 |
|---|---|---|---|
| group | string | 否 | 群组名称。 说明: 多个相同群组名称的CheckboxGroup,仅第一个CheckboxGroup生效。 |
常用属性
| 名称 | 参数类型 | 描述 |
|---|---|---|
| selectAll | boolean | 设置是否全选。 默认值:false,若同组的Checkbox设置了select属性,则Checkbox的优先级高。 该属性支持$$,双向绑定变量。 |
| selectedColor | ResourceColor | 设置被选中或部分选中状态的颜色。 |
| unselectedColor | ResourceColor | 设置非选中状态边框颜色。 |
二、实例实现
2.1 实现购物车购物物品总价钱计算 如图:
2.2 静态结构
2.2.1 静态结构代码
interface GoodInfo {
id: number // 商品ID
name: string // 商品名称
img: ResourceStr// 商品图片
price: number// 商品价格
count: number// 商品数量
}
@Entry
@Component
struct CartPage {
goodList: GoodInfo[] = [
{
id: 1,
name: 'CP 正大 鲜鸡蛋 30枚 1.59kg 早餐食材 优质蛋白 简装 年货礼盒',
img: 'https://img10.360buyimg.com/n2/s240x240_jfs/t1/123263/8/18451/99918/5fadf6d2E23e7dd22/8ba19066638ac30c.jpg!q70.jpg.webp',
price: 25.8,
count: 2
},
{
id: 2,
name: '小汤山 北京 西兰花 270g 基地直供新鲜蔬菜',
img: 'https://img14.360buyimg.com/n2/s240x240_jfs/t1/169777/20/30573/169612/63439079E163426f6/918bf9a3daff559a.jpg!q70.jpg.webp',
price: 14.9,
count: 3
},
{
id: 3,
name: '塞莫诗 丁腈手套加长款30只/包 加厚型 防油防水耐污 白色中号',
img: 'https://img10.360buyimg.com/n2/s240x240_jfs/t1/98273/24/30795/51511/641a9523F88afbc89/7ec4f5a970449aaf.jpg!q70.jpg.webp',
price: 39.9,
count: 3
},
{
id: 4,
name: '努比亚(nubia)红魔9 Pro+全面屏下游戏手机 16GB+512GB氘锋透明暗夜 骁龙8Gen3 165W快充 5500mAh 5G电竞手机',
img: 'https://img11.360buyimg.com/n2/s240x240_jfs/t1/154052/34/22342/2570546/65f39e22F565a8c81/9fc2c1c50e7abe57.jpg!q70.jpg.webp',
price: 5999,
count: 2
},
{
id: 5,
name: '炊大皇 炒锅 304不锈钢炒菜锅煎锅 平底不粘炒锅32cm 可立可视盖不挑灶',
img: 'https://img13.360buyimg.com/n2/s240x240_jfs/t1/195539/22/41621/175614/65f3fdecF15a476ce/c9ba416cbce6d9cc.jpg!q70.jpg.webp',
price: 139,
count: 3
}, {
id: 6,
name: '西贝莜面村梅菜扣肉200g 肥瘦相间五花肉酥软不腻 预制菜 新包装',
img: 'https://img10.360buyimg.com/n2/s240x240_jfs/t1/168770/10/43511/163526/65d45a8aF9e865e6b/66a9d6484d8ab6e3.jpg!q70.jpg.webp',
price: 29.9,
count: 4
}
]
build() {
Column() {
// 商品列表
List() {
ListItem() {
Row({ space: 10 }) {
Checkbox()
.selectedColor('#eb4646')
Image('https://img11.360buyimg.com/n2/s240x240_jfs/t1/154052/34/22342/2570546/65f39e22F565a8c81/9fc2c1c50e7abe57.jpg!q70.jpg.webp')
.width(100)
.borderRadius(10)
Column() {
Text('商品名')
.maxLines(2)
.textOverflow({ overflow: TextOverflow.Ellipsis })
Blank()
Row() {
Text(`¥10.0`)
.fontColor(Color.Red)
.fontSize(20)
Blank()
Text(`x 10`)
.fontColor(Color.Gray)
.fontSize(14)
}
.width('100%')
}
.height('100%')
.layoutWeight(1)
}
.height(110)
.padding(10)
}
}
.divider({ strokeWidth: 1, startMargin: 40, endMargin: 20 })
.edgeEffect(EdgeEffect.Fade)
.layoutWeight(1)
// 结算
Row() {
CheckboxGroup()
.selectedColor('#d8534c')
Text('全选')
Text() {
Span('合计')
Span(`¥0.0`)
.fontColor('#d8534c')
}
.layoutWeight(1)
.textAlign(TextAlign.Center)
Button('结算')
.type(ButtonType.Normal)
.height('100%')
.width(120)
.backgroundColor('#d8534c')
}
.height(50)
.backgroundColor(Color.White)
.width('100%')
}
.height('100%')
}
}
2.3 业务需求
2.3.1 将全部的商品信息全部渲染出来
技术1: ForEach来遍历数组中的元素来渲染
技术2:CheckboxGroup中有个Onchange()事件来实现用户点击了哪个商品
2.3.2 具体实现
1.1 遍历数组
1.2 将数据渲染到页面上
// 商品列表
List() {
ForEach(this.goodList,(item:GoodInfo)=>{
ListItem() {
Row({ space: 10 }) {
Checkbox({name:item.id.toString(),group:'foods'})
.selectedColor('#eb4646')
Image(item.img)
.width(100)
.borderRadius(10)
Column() {
Text(item.name)
.maxLines(2)
.textOverflow({ overflow: TextOverflow.Ellipsis })
Blank()
Row() {
Text(`¥${item.price}`)
.fontColor(Color.Red)
.fontSize(20)
Blank()
Text(`x ${item.count}`)
.fontColor(Color.Gray)
.fontSize(14)
}
.width('100%')
}
.height('100%')
.layoutWeight(1)
}
.height(110)
.padding(10)
}
})
}
.divider({ strokeWidth: 1, startMargin: 40, endMargin: 20 })
.edgeEffect(EdgeEffect.Fade)
.layoutWeight(1)
按照上面的操作后你就会得到下面渲染后的页面效果了:
三、计算总计
此时你已经将数据全部渲染到页面上,下一步需要考虑用户点击选择框时,算出总价格是多少? 那么根据技术点2可以解决用户选择了那些商品,当用户点击选择框时就会触发Onchange()这个事件,然后根据触发事件返回的name值去匹配数组中元素中的name值,将这些商品筛选出来在进行相加就可以了。
3.1 调用Onchange()事件
CheckboxGroup({group:'foods'})
.selectedColor('#d8534c')
.onChange((res)=>{
let news = this.goodList.filter((item)=>{
return res.name.includes(item.id.toString())
})
this.sum = 0
news.forEach((item)=>{
return this.sum+=item.price*item.count
})
3.2 完整代码
interface GoodInfo {
id: number
name: string
img: ResourceStr
price: number
count: number
}
@Entry
@Component
struct CartPage {
goodList: GoodInfo[] = [
{
id: 1,
name: 'CP 正大 鲜鸡蛋 30枚 1.59kg 早餐食材 优质蛋白 简装 年货礼盒',
img: 'https://img10.360buyimg.com/n2/s240x240_jfs/t1/123263/8/18451/99918/5fadf6d2E23e7dd22/8ba19066638ac30c.jpg!q70.jpg.webp',
price: 25.8,
count: 2
},
{
id: 2,
name: '小汤山 北京 西兰花 270g 基地直供新鲜蔬菜',
img: 'https://img14.360buyimg.com/n2/s240x240_jfs/t1/169777/20/30573/169612/63439079E163426f6/918bf9a3daff559a.jpg!q70.jpg.webp',
price: 14.9,
count: 3
},
{
id: 3,
name: '塞莫诗 丁腈手套加长款30只/包 加厚型 防油防水耐污 白色中号',
img: 'https://img10.360buyimg.com/n2/s240x240_jfs/t1/98273/24/30795/51511/641a9523F88afbc89/7ec4f5a970449aaf.jpg!q70.jpg.webp',
price: 39.9,
count: 3
},
{
id: 4,
name: '努比亚(nubia)红魔9 Pro+全面屏下游戏手机 16GB+512GB氘锋透明暗夜 骁龙8Gen3 165W快充 5500mAh 5G电竞手机',
img: 'https://img11.360buyimg.com/n2/s240x240_jfs/t1/154052/34/22342/2570546/65f39e22F565a8c81/9fc2c1c50e7abe57.jpg!q70.jpg.webp',
price: 5999,
count: 2
},
{
id: 5,
name: '炊大皇 炒锅 304不锈钢炒菜锅煎锅 平底不粘炒锅32cm 可立可视盖不挑灶',
img: 'https://img13.360buyimg.com/n2/s240x240_jfs/t1/195539/22/41621/175614/65f3fdecF15a476ce/c9ba416cbce6d9cc.jpg!q70.jpg.webp',
price: 139,
count: 3
}, {
id: 6,
name: '西贝莜面村梅菜扣肉200g 肥瘦相间五花肉酥软不腻 预制菜 新包装',
img: 'https://img10.360buyimg.com/n2/s240x240_jfs/t1/168770/10/43511/163526/65d45a8aF9e865e6b/66a9d6484d8ab6e3.jpg!q70.jpg.webp',
price: 29.9,
count: 4
}
]
@State sum:number = 0
build() {
Column() {
// 顶部图片
// Image($r('app.media.cart_top'))
// .width('100%')
// 商品列表
List() {
ForEach(this.goodList,(item:GoodInfo)=>{
ListItem() {
Row({ space: 10 }) {
Checkbox({name:item.id.toString(),group:'foods'})
.selectedColor('#eb4646')
Image(item.img)
.width(100)
.borderRadius(10)
Column() {
Text(item.name)
.maxLines(2)
.textOverflow({ overflow: TextOverflow.Ellipsis })
Blank()
Row() {
Text(`¥${item.price}`)
.fontColor(Color.Red)
.fontSize(20)
Blank()
Text(`x ${item.count}`)
.fontColor(Color.Gray)
.fontSize(14)
}
.width('100%')
}
.height('100%')
.layoutWeight(1)
}
.height(110)
.padding(10)
}
})
}
.divider({ strokeWidth: 1, startMargin: 40, endMargin: 20 })
.edgeEffect(EdgeEffect.Fade)
.layoutWeight(1)
// 结算
Row() {
CheckboxGroup({group:'foods'})
.selectedColor('#d8534c')
.onChange((res)=>{
let news = this.goodList.filter((item)=>{
return res.name.includes(item.id.toString())
})
this.sum = 0
news.forEach((item)=>{
return this.sum+=item.price*item.count
})
})
Text('全选')
Text() {
Span('合计')
Span(`¥${this.sum}`)
.fontColor('#d8534c')
}
.layoutWeight(1)
.textAlign(TextAlign.Center)
Button('结算')
.type(ButtonType.Normal)
.height('100%')
.width(120)
.backgroundColor('#d8534c')
}
.height(50)
.backgroundColor(Color.White)
.width('100%')
}
.height('100%')
}
}
这样就可以实现用户选择商品时计算商品的总价