HarmonyOS 鸿蒙Next 如何实现List中 item 左边 checkbox 滑动多选
HarmonyOS 鸿蒙Next 如何实现List中 item 左边 checkbox 滑动多选
滑动效果如下
https://developer.huawei.com/consumer/cn/doc/design-guides-V1/select-box-0000001156786993-V1
这里的滑动多选,我没找到代码实现文档。
这种效果需要如何实现。
更多关于HarmonyOS 鸿蒙Next 如何实现List中 item 左边 checkbox 滑动多选的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
1、通过onAreaChange()方法记录ListItem的area信息,HSFileDataModel.area;
2、List组件添加onTouch()事件;
3、手势在List组件内滑动时,计算选中的ListItem。
计算逻辑:getOnTouchItem()方法中的,(windowX >= x) && (windowX <= x + width) && (windowY >= y) && (windowY <= y + height)。windowX、windowY触摸位置在窗口中的x、y坐标,area.globalPosition.x、area.globalPosition.y目标元素左上角相对页面左上角的坐标
代码如下:
TimeLineView.ets:
[@Builder](/user/Builder)
private ListView() {
List({ scroller: this.scroller }) {
...
}
.onTouch((event: TouchEvent) => {
if (!this.isOnTouchInParent(event)) {
return
}
// 触摸按下,记录按下的item
if (event.type === TouchType.Down) {
console.log(`TouchEvent:::::::::::::Down::isOnTouchInParent: ${event.touches[0].windowX}, ${event.touches[0].windowX}`)
const imageItem = this.getOnTouchItem(event)
if (imageItem) {
console.log(`TouchEvent:::::::::::::Down::${imageItem.index}`)
this.tempImage = imageItem
}
}
// 触摸抬起,清空tempImage
if (event.type === TouchType.Up && this.isLongPress) {
console.log(`TouchEvent:::::::::::::Up::isOnTouchInParent: ${event.touches[0].windowX}, ${event.touches[0].windowX}`)
// const imageItem = this.getOnTouchItem(event)
this.tempImage = null
// 遍历dataSource,设置单次操作选中项
const data = this.dataSource.getFullData()
for (const item of data) {
for (const imageItem of item.fileItem || []) {
if (imageItem.tempSelected) {
imageItem.isSelected = true
// 重置
imageItem.tempSelected = false
}
}
}
console.log(`TouchEvent:::::::::::::Up::isOnTouchInParent:: ${JSON.stringify(data[0].fileItem)}`)
}
// 滑动时,计算起点-终点,并将范围内的item修改为selected状态
if (event.type === TouchType.Move && this.isLongPress) {
console.log(`TouchEvent:::::::::::::Move::isOnTouchInParent: ${event.touches[0].windowX}, ${event.touches[0].windowX}`)
// 起点不存在
if (!this.tempImage) {
return
}
const imageItem = this.getOnTouchItem(event)
// 若起点-终点item不一致
if (imageItem && imageItem.index !== this.tempImage.index) {
const start = Math.min(imageItem.index, this.tempImage.index)
const end = Math.max(imageItem.index, this.tempImage.index)
// 设置范围选中
const data = this.dataSource.getFullData()
for (const item of data) {
for (const imageItem of item.fileItem || []) {
if (imageItem.index >= start && imageItem.index <= end) {
// 增加临时选中变量 tempSelected,在单次滑动多选操作中,记录tempSelected,在TouchType.Up中修改为实际选中isSelected
imageItem.tempSelected = true
} else {
imageItem.tempSelected = false
}
}
}
}
}
})
}
// 判断滑动是否处于父容器List组件内
isOnTouchInParent(event: TouchEvent): boolean {
if (event.touches[0].x > 0 && event.touches[0].y > 0) {
return true
}
return false
}
getOnTouchItem(event: TouchEvent): HSFileDataModel | null {
const windowX = event.touches[0].windowX
const windowY = event.touches[0].windowY
const data = this.dataSource.getFullData()
for (const item of data) {
const imageItem = (item.fileItem || []).find(image => {
const area = image.area
if (!area || !area.globalPosition.x || !area.globalPosition.y) {
return false
}
const x = area.globalPosition.x as number
const y = area.globalPosition.y as number
const width = area.width as number
const height = area.height as number
// 判断是否为触摸item
return (windowX >= x) && (windowX <= x + width) && (windowY >= y) && (windowY <= y + height)
})
if (imageItem) {
console.log(`TouchEvent:::::::::::::match::${imageItem.index}`)
console.log(`TouchEvent:::::::::::::Down::touchXY::${windowX}::${windowY}`)
console.log(`TouchEvent:::::::::::::Down::imagePoint::${imageItem.area?.globalPosition.x}::${imageItem.area?.globalPosition.y}`)
return imageItem
}
}
return null;
}
ListItemView.ets:
Column() {
Stack({ alignContent: Alignment.TopEnd }) {
...
}
.onAppear(() => {
// this.fileItem.isSelected = this.itemSelectMap.get(this.fileItem.index)!
})
}
.onAreaChange((oldValue: Area, newValue: Area) => {
// 保存image的坐标信息
this.fileItem.area = newValue
})
HSFileDataModel.ets:
export class HSFileDataModel {
...
tempSelected: boolean = false // 临时选中
area?: Area
}
更多关于HarmonyOS 鸿蒙Next 如何实现List中 item 左边 checkbox 滑动多选的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
在HarmonyOS鸿蒙Next系统中,实现List中item左边checkbox的滑动多选功能,可以通过以下方式实现:
-
UI布局:在XML布局文件中,为List的每个item定义一个Checkbox组件,并将其放置在左侧。确保Checkbox的ID和事件绑定正确。
-
数据绑定:为每个item的数据模型添加一个布尔类型的字段,用于表示Checkbox的选中状态。在数据绑定时,将该字段与Checkbox的选中状态绑定。
-
滑动监听:为List添加滑动监听事件,当用户滑动并选中或取消选中多个item时,通过监听事件更新数据模型中对应item的选中状态。
-
批量操作:如果需要实现全选、全不选或反选功能,可以在事件处理函数中遍历数据模型,批量更新Checkbox的选中状态。
-
UI刷新:每次更新数据模型的选中状态后,确保UI能够即时刷新,以反映最新的选中情况。
-
状态保存:在适当的时候,如用户离开页面或应用进入后台时,保存当前所有Checkbox的选中状态,以便用户再次进入时能够恢复。
以上步骤概述了在HarmonyOS鸿蒙Next系统中实现List中item左边checkbox滑动多选的基本方法。如果问题依旧没法解决请联系官网客服,官网地址是:https://www.itying.com/category-93-b0.html