易得天气
完成了城市列表的拖拽排序功能
给item添加手势
.gesture(
GestureGroup(GestureMode.Sequence,
LongPressGesture()
.onAction(() => {
if (this.toEditMode) {
this.toEditMode(this.cityData)
}
this.onLongPress()
}),
PanGesture()
.onActionUpdate((event: GestureEvent) => {
this.onItemMove(event.offsetY)
})
.onActionEnd(() => {
this.onItemDrop()
})
).onCancel(() => {
if (!this.isLongPress) {
return;
}
this.onItemDrop()
})
)
给拖拽图片添加手势
Image($r('app.media.ic_menu_icon'))
.width(24)
.height(24)
.colorFilter(ColorUtils.translateColor($r('app.color.special_white')))
.draggable(false)
.gesture(
GestureGroup(GestureMode.Sequence,
PanGesture()
.onActionStart(() => {
console.log('onActionStart')
this.onMenuPress()
})
.onActionUpdate((event: GestureEvent) => {
this.onItemMove(event.offsetY)
})
.onActionEnd(() => {
this.onItemDrop()
})
).onCancel(() => {
if (!this.isMenuPress) {
return;
}
this.onItemDrop()
})
)
手势监听调用的方法
按下手势监听:
onLongPress() {
const enable = this.onReorderStart ? this.onReorderStart() : true
if (enable) {
this.zIndexValue = 1
this.isLongPress = true
this.dragRefOffset = 0
}
}
onMenuPress() {
const enable = this.onReorderStart ? this.onReorderStart() : true
if (enable) {
this.zIndexValue = 1
this.isMenuPress = true
this.dragRefOffset = 0
}
}
移动手势监听:
onItemMove(offsetY: number) {
if (!this.isLongPress && !this.isMenuPress) {
return
}
this.offsetY = offsetY - this.dragRefOffset
const direction = this.offsetY > 0 ? 1 : -1
if (Math.abs(this.offsetY) > ITEM_HEIGHT / 2) {
if (this.index === 0 && direction === -1) {
return
}
if (this.index === this.length - 1 && direction === 1) {
return
}
// 目标位置索引
const target = this.index + direction
if (this.beforeChange) {
if (this.beforeChange(target)) {
return
}
}
animateTo({ curve: Curve.Friction, duration: 300 }, () => {
this.offsetY -= direction * ITEM_HEIGHT
this.dragRefOffset += direction * ITEM_HEIGHT
if (target !== -1 && target <= this.length) {
console.log('changeItem index = ' + this.index + ' target = ' + target)
if (this.onChangeItem) {
this.onChangeItem(this.index, target)
}
}
})
}
}
手势结束监听:
onItemDrop() {
if (this.isLongPress || this.isMenuPress) {
this.isLongPress = false
this.isMenuPress = false
this.dragRefOffset = 0;
if (this.onReorderDone) {
this.onReorderDone()
}
animateTo({
curve: curves.interpolatingSpring(14, 1, 170, 17), onFinish: () => {
this.zIndexValue = 0
}
}, () => {
this.offsetY = 0
})
}
}
CityManagerItem
CityManagerItem({
cityData: cityData,
index: this.addedCityData?.findIndex(it => it.cityid == cityData.cityid),
length: this.addedCityData?.length,
isEditMode: this.cityManagerVm.isEditMode,
isSelected: this.cityManagerVm.isSelected(cityData),
toEditMode: (cityData) => {
// 编辑模式
this.cityManagerVm.toEditMode(this.addedCityData?.length ?? 0, cityData)
},
onItemClick: (cityData) => {
if (this.cityManagerVm.isEditMode) {
// 编辑模式下选中item
this.cityManagerVm.selected(cityData)
}
},
onRemoveItem: (cityData) => {
// 删除item
this.cityManagerVm.removeItem(cityData, this.addedCityData)
},
onReorderStart: () => {
// 开始拖拽排序的回调
// 返回值为true表示可以拖拽
// 此处表示不是定位城市才可进行拖拽排序
this.cityManagerVm.deleteButtonEnable = false
return !cityData.isLocationCity
},
beforeChange: (target) => {
// 如果返回值是true 表示不能交换item位置
const targetCityData = this.addedCityData?.[target]
return targetCityData?.isLocationCity ?? false
},
onChangeItem: (from, to) => {
// 当item交换位置时 列表数据需要交换
if (ArrayUtil.isNotEmpty(this.addedCityData)) {
const tmp = this.addedCityData?.splice(from, 1)
this.addedCityData?.splice(to, 0, tmp![0])
}
},
onReorderDone: async () => {
// 拖拽排序结束的回调
this.cityManagerVm.deleteButtonEnable = true
const currentCityIdList =
this.addedCityData!.map(it => it.isLocationCity ? Constants.LOCATION_CITY_ID : it.cityid ?? '')
await PreferencesUtil.put(Constants.CURRENT_CITY_ID_LIST, currentCityIdList)
}
})