鸿蒙开发: 案例集合List:ListItem侧滑(删除、收藏)

作者:汉堡黄•᷄ࡇ•᷅日期:2025/12/4

🎯 案例集合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侧滑(删除、收藏)》 是转载文章,点击查看原文


相关推荐


1024层网络让强化学习性能飙升50倍,NeurIPS 2025最佳论文揭示深度scaling的力量
CoovallyAIHub2025/12/1

在自然语言处理和计算机视觉领域,模型规模的扩大已经催生了无数突破,但强化学习(RL)领域的类似进展却一直难以实现。大多数RL研究仍在使用2-5层的浅层网络架构,而如今的LLaMA和Stable Diffusion等模型早已拥有数百层。 NeurIPS 2025最佳论文奖由普林斯顿大学与OpenAI的合作研究,他们成功将RL网络深度扩展至1024层,在自监督强化学习任务上实现了性能2-50倍的提升。这项研究不仅证明了深度scaling对RL的有效性,还观察到了与模型规模相关的“突现现象”——当网络


Scala 安装及环境配置
froginwe112025/11/28

Scala 安装及环境配置 引言 Scala 是一门多范式编程语言,它可以无缝地与 Java 代码混合,同时拥有函数式编程的特性。本文将详细介绍 Scala 的安装过程以及环境配置,帮助您快速上手 Scala 开发。 Scala 安装 1. 下载 Scala 首先,您需要从 Scala 官方网站 下载 Scala 的安装包。根据您的操作系统选择合适的版本进行下载。 2. 安装 Scala 以下是不同操作系统的安装步骤: Windows 双击下载的安装包,开始安装。 选


推荐 5 个 yyds 的 Claude Skills 开源项目。
逛逛GitHub2025/11/26

前段时间,Anthropic 推出了 Claude Skills 能力。 这是一种模块化能力扩展机制。有了它你不就用给 AI 重复解释了。 你可以把所有想让 Claude 吸取的经验都写到一个 Skill.md 文件里面。这个文件可以理解为是一份详细的指令说明书、可执行的脚本或相关资源,专门用于完成某项特定任务 。感兴趣可以看看下面这个文章,有详细描述。 开源地址:https://www.claude.com/blog/skills 比如你搞了一个 Skill.md 文件,里面放了 AI 生


Linux——web服务介绍和nginx编译安装
不想画图2025/11/24

文章目录 前言一、web服务概念1、web概念2、web特点3、B/S架构模型4、web 请求与响应过程5、静态资源与动态资源6、总结 二、http和https协议1、http和https的区别2、https握手流程3、http状态码3.1、汇总说明3.2、详细状态码说明3.3 总结 4、常用http状态码 三、Nginx概念1、nginx介绍2、nginx和apache差异3、nginx进程结构3.1、web请求处理机制3.2、nginx主进程和工作流的调用流程3.3、工作进程


力扣日刷251120
倦王2025/11/22

今天跟女朋友打了一会三角洲,现在才开始做题,争取也完成3道以上吧哈哈哈哈 第一题: 这一题,我先看了题解,题解中暴力求解的办法就是把每次遇到的指针(head)都加入到一个set()当中,然后循环体head,当head非空时,进行一个判断,如果head在set中出现过就回Ture,反之就False。下面是官方题解: class Solution: def hasCycle(self, head: ListNode) -> bool: seen = set()


Swift6 @retroactive:Swift 的重复协议遵循陷阱
RickeyBoy2025/11/20

欢迎大家给我点个 star!Github: RickeyBoy 背景:一个看似简单的 bug App 内有一个电话号码输入界面,在使用时用户需要从中选择注册电话对应的国家,以获取正确的电话区号前缀(比如中国是 +86,英国是 +44 等)。 Step 1:入口Step 2:缺少区号期望结果 这是一个看似很简单的 bug,无非就是写 UI 的时候漏掉了区号,那么把对应字段拼上去就行了嘛。不过一番调查之后发现事情没有那么简单。 列表是一个公用组件,我们需要在列表中显示


如视发布空间大模型Argus1.0,支持全景图等多元输入,行业首创!
机器之心2025/11/19

近来,世界模型(World Model)很火。多个 AI 实验室纷纷展示出令人惊艳的 Demo:仅凭一张图片甚至一段文字,就能生成一个可交互、可探索的 3D 世界。这些演示当然很是炫酷,它们展现了 AI 强大的生成能力。 但一个关键问题随之而来:这些由 AI 生成的世界中,绝大部分事物都是模型想象和虚构的。 如果我们不满足于「创造」一个虚拟世界,而是想把我们当下生活的这个真实世界(比如我们的家、办公室、工厂和城市)完整地变成一个可交互、可计算的 3D 世界呢? 这正是如视(Realsee)想要解


pytest1-接口自动化测试场景
文人sec2025/11/17

课程:B站大学 记录python学习,直到学会基本的爬虫,使用python搭建接口自动化测试,后续进阶UI自动化测试 接口自动化测试 接口自动化测试的场景测试金字塔模型自动化测试前需要思考什么?Pytest是什么?Pytest 有哪些格式要求?在pycharm下安装pytestpytest知识点测试用例示例类级别的用例示例断言测试装置介绍参数化参数化测试函数使用Mark:标记测试用例Skip:使用场景pytest命令运行测试用例文件pytest中执行顺序如何调整pytest中py文件执


Next.js第五章(动态路由)
小满zs2025/11/16

动态路由 动态路由是指在路由中使用方括号[]来定义路由参数,例如/blog/[id],其中[id]就是动态路由参数,因为在某些需求下,我们需要根据不同的id来显示不同的页面内容,例如商品详情页,文章详情页等。 基本用法[slug] 使用动态路由只需要在文件夹名加上方括号[]即可,例如[id],[params]等,名字可以自定义。 来看demo: 我们在app/shop目录下创建一个[id]目录 //app/shop/[id]/page.tsx export default function Pa


基于脚手架微服务的视频点播系统-脚手架开发部分(完结)elasticsearch与libcurl的简单使用与二次封装及bug修复
加班敲代码的Plana2025/11/15

基于脚手架微服务的视频点播系统-脚手架开发部分elasticsearch与libcurl的简单使用与二次封装及bug修复-完结 1.ElasticClient的使用1.1ES检索原理正排索引倒排索引 1.2ES核心概念1.2.1索引(index)1.2.2类型(Field)1.2.3字段(Field)1.2.4映射(mapping)1.2.5文档(document) 1.3 Kibana访问es进行测试1.3.1创建索引1.3.2新增数据1.3.3查看并搜索数据1.3.4删除索引

首页编辑器站点地图

本站内容在 CC BY-SA 4.0 协议下发布

Copyright © 2025 聚合阅读