🎯 案例集合List:ListItem侧滑(删除、收藏)
🌍 案例集合List
🚪 最近开启了学员班级点我欢迎加入(学习相关知识可获得定制礼盒)
🏷️ 效果图
🏷 原生

🏷 自定义

📖 参考
🧩 拆解
- 原生ListItem组件自带侧滑
1/** 2 * 用户类 3 */ 4@ObservedV2 5class UserInfo { 6 @Trace label: string = '' 7 @Trace collect: boolean = false 8 id: number = 0 9 10 changeCollect() { 11 this.collect = !this.collect 12 } 13} 14 15/** 16 * 模拟数据 17 */ 18const listData: string[] = ['购物', '体育', '服装', '军事', '电商', '娱乐', '科技'] 19 20@ComponentV2 21export struct ListSlideDelete { 22 /** 23 * 模拟数据 24 */ 25 @Local mockData: UserInfo[] = [] 26 27 aboutToAppear(): void { 28 this.InitData() 29 } 30 31 /** 32 * 初始化数据 33 */ 34 InitData() { 35 for (let i = 0; i < listData.length; i++) { 36 let myInfo: UserInfo = new UserInfo() 37 myInfo.label = listData[i] 38 myInfo.collect = false 39 myInfo.id = i 40 this.mockData.push(myInfo) 41 } 42 } 43 44 /** 45 * 删除列表数据项 46 * @param idx 47 */ 48 delListItem(idx: number) { 49 this.mockData.splice(idx, 1) 50 } 51 52 @Builder 53 listItemEnd(item: UserInfo, idx: number) { 54 Row({ space: 5 }) { 55 Text('收藏') 56 .width(50) 57 .aspectRatio(1) 58 .fontSize(20) 59 .fontWeight(FontWeight.Regular) 60 .borderRadius(50) 61 .backgroundColor(item.collect ? Color.Orange : Color.Gray) 62 .textAlign(TextAlign.Center) 63 .onClick(() => item.changeCollect()) 64 Text('删除') 65 .width(50) 66 .aspectRatio(1) 67 .fontSize(20) 68 .fontWeight(FontWeight.Regular) 69 .borderRadius(50) 70 .backgroundColor('#80ff8b8b') 71 .textAlign(TextAlign.Center) 72 .onClick(() => this.delListItem(idx)) 73 } 74 .padding(5) 75 .justifyContent(FlexAlign.Center) 76 } 77 78 build() { 79 Column() { 80 List({ space: 20 }) { 81 ForEach(this.mockData, (item: UserInfo, idx: number) => { 82 ListItem() { 83 Text(item.label) 84 .width('100%') 85 .height(100) 86 .fontSize(20) 87 .borderRadius(20) 88 .textAlign(TextAlign.Center) 89 .backgroundColor('#4dfdddcb') 90 } 91 .swipeAction( 92 { 93 end: { 94 builder: () => this.listItemEnd(item, idx), 95 // onAction: () => this.delListItem(idx), TODO:放开:侧滑到最左侧也可删除 96 } 97 } 98 ) 99 }, (item: UserInfo) => item.id.toString()) 100 } 101 .layoutWeight(1) 102 .scrollBar(BarState.Off) // 关闭滚动条 103 .edgeEffect(EdgeEffect.None) // 关闭滚动动效 104 } 105 .width('100%') 106 .height('100%') 107 .padding(15) 108 } 109} 110
- 自定义ListItem组件自带侧滑
1/** 2 * 用户类 3 */ 4@ObservedV2 5class UserInfo { 6 @Trace label: string = '' 7 @Trace collect: boolean = false 8 @Trace translate: number = 0 9 id: number = 0 10 11 changeCollect() { 12 this.collect = !this.collect 13 } 14} 15 16/** 17 * 模拟数据 18 */ 19const listData: string[] = ['购物', '体育', '服装', '军事', '电商', '娱乐', '科技'] 20 21@ComponentV2 22export struct CustomListSlideDelete { 23 /** 24 * 模拟数据 25 */ 26 @Local mockData: UserInfo[] = [] 27 /** 28 * 最大滑动距离(listItemEnd组件宽度) 29 */ 30 private maxTranslate: number = -110 31 /** 32 * 滑动距离的一半 33 */ 34 private halfOfTheDistance: number = -65 35 /** 36 * 最小滑动距离 37 */ 38 private defTranslate: number = 0 39 40 aboutToAppear(): void { 41 this.InitData() 42 } 43 44 /** 45 * 初始化数据 46 */ 47 InitData() { 48 for (let i = 0; i < listData.length; i++) { 49 let myInfo: UserInfo = new UserInfo() 50 myInfo.label = listData[i] 51 myInfo.collect = false 52 myInfo.id = i 53 myInfo.translate = 0 54 this.mockData.push(myInfo) 55 } 56 } 57 @Builder 58 listItemEnd(item: UserInfo, idx: number) { 59 Row({ space: 5 }) { 60 Text('收藏') 61 .width(50) 62 .aspectRatio(1) 63 .fontSize(20) 64 .fontWeight(FontWeight.Regular) 65 .borderRadius(50) 66 .backgroundColor(item.collect ? Color.Orange : Color.Gray) 67 .textAlign(TextAlign.Center) 68 .onClick(() => item.changeCollect()) 69 Text('删除') 70 .width(50) 71 .aspectRatio(1) 72 .fontSize(20) 73 .fontWeight(FontWeight.Regular) 74 .borderRadius(50) 75 .backgroundColor('#80ff8b8b') 76 .textAlign(TextAlign.Center) 77 .onClick(() => this.mockData.splice(idx, 1)) 78 } 79 .padding({ left: 5 }) 80 .width(110) 81 .height('100%') 82 .justifyContent(FlexAlign.Center) 83 } 84 85 build() { 86 Column() { 87 List({ space: 20 }) { 88 ForEach(this.mockData, (item: UserInfo, idx: number) => { 89 ListItem() { 90 Row() { 91 Row() { 92 Text(item.label) 93 .fontSize(20) 94 } 95 .width('100%') 96 .height('100%') 97 .justifyContent(FlexAlign.Center) 98 99 this.listItemEnd(item, idx) 100 } 101 .width('100%') 102 .height(100) 103 .borderRadius(20) 104 .backgroundColor('#4dfdddcb') 105 .translate({ x: item.translate }) 106 .animation({ duration: 200, curve: Curve.EaseOut }) 107 // 支持手动滑动手势 108 .gesture( 109 PanGesture({ direction: PanDirection.Horizontal }) 110 .onActionUpdate((event: GestureEvent) => { 111 // 左负数, 右正数字 112 const offsetX = event.offsetX 113 // 当前listItem的滑动 114 const curTranslate = item.translate 115 // 默认滑动值 116 const defTranslate = this.defTranslate 117 // 最大滑动值 118 const maxTranslate = this.maxTranslate 119 120 // 规避左右滑动的时候符合最小 最大滑动值,其余情况不滑动 121 if (curTranslate === defTranslate && offsetX > 0 || curTranslate === maxTranslate && offsetX < 0) { 122 return 123 } 124 125 // 只允许在0 ~ -110滑动 126 if (curTranslate <= defTranslate && curTranslate >= maxTranslate) { 127 // 小于0 认为在向左滑动 128 if (offsetX < 0) { 129 if (-(Math.abs(curTranslate) + Math.abs(event.offsetX)) <= -110) { 130 // 小于-110的时候给-110 131 this.mockData[idx].translate = maxTranslate 132 return 133 } 134 this.mockData[idx].translate = -(Math.abs(curTranslate) + Math.abs(event.offsetX)) 135 } 136 // 认为在向右滑动 137 else { 138 if (curTranslate + event.offsetX >= 0) { 139 // 大于0的时候给0 140 this.mockData[idx].translate = defTranslate 141 return 142 } 143 this.mockData[idx].translate = curTranslate + event.offsetX 144 } 145 } 146 }) 147 .onActionEnd(() => { 148 // 滑动结束后自动调整状态(超过一半则完全展开,否则收起) 149 if (this.mockData[idx].translate < this.halfOfTheDistance) { 150 this.mockData[idx].translate = this.maxTranslate 151 return 152 } 153 this.mockData[idx].translate = this.defTranslate 154 }) 155 ) 156 } 157 }, (item: UserInfo) => item.id.toString()) 158 } 159 .layoutWeight(1) 160 .scrollBar(BarState.Off) // 关闭滚动条 161 .edgeEffect(EdgeEffect.None) // 关闭滚动动效 162 } 163 .width('100%') 164 .height('100%') 165 .padding(15) 166 } 167} 168
🌸🌼🌺
《鸿蒙开发: 案例集合List:ListItem侧滑(删除、收藏)》 是转载文章,点击查看原文。
