资讯动态

swipe-item-cj 侧滑组件实战指南:SwipeItemLayout 左右滑动容器 API 详解与源码剖析

发布时间:2026/10/15 2:40:26 来源:尧图企业网站定制
UI组件移动开发OpenHarmony【免费下载链接】swipe-item-cj自定义侧滑操作UI组件项目地址https://gitcode.com/Cangjie-TPC/swipe-item-cj点击查看免费下载swipe-item-cj 是一个基于 Cangjie仓颉语言、运行于 OpenHarmony 应用层的自定义侧滑操作 UI 组件库核心能力是为任意内容组件如列表项附加左侧与右侧两个可滑出的操作区。本文以特性文档 doc/feature_api.md 为主线完整讲解SwipeItemLayout组件全部 API 参数、可运行的示例代码、滑动交互的底层实现原理并给出接入自有工程的两种方式读完即可在 Cangjie 应用中实现左滑删除、右滑选择等交互。一、组件定位为列表项附加左右操作区的滑动容器按特性文档的定位swipe-item-cj 支持组件左右滑动仓库 README 进一步描述为支持组件左侧和右侧的滑动布局。它不依赖任何第三方滑动框架而是由swipeitem库中的SwipeItemLayout组件独立实现一套手势识别 位移动画逻辑典型应用场景包括列表项左滑露出删除操作如邮件、消息列表列表项右滑露出选择/置顶/收藏等操作全宽操作面板右滑区域占满屏幕宽度承载图文、按钮组合仓库示例LargrWidthView即是。仓库目录结构与本文主题的对应关系如下目录/文件作用swipeitem/src/main/cangjie/src/swipe_item_layout.cj左右侧滑动容器核心实现entry/src/main/cangjie/src/page/三个示例页面单条、列表、全宽doc/feature_api.md组件 API 特性文档本文主体CHANGELOG.md版本记录v0.0.1 支持左右侧滑动布局二、SwipeItemLayout 组件 API 全量参数说明SwipeItemLayout是一个Component公开组件对外暴露 12 个参数含 3 个BuilderParam、2 个Link。特性文档中的声明如下Component public class SwipeItemLayout { BuilderParam let surfaceView: (String, Int64) - Unit // 滑动组件 Link var itemContent: String // 组件内容 Link var itemId: Int64 0 // 组件索引 BuilderParam let swipeRightView: (Int64) - Unit // 设置右侧滑动布局样式 BuilderParam let swipeLeftView: (Int64) - Unit // 设置左侧滑动布局样式 var mWidth: Float64 // 设置组件宽度单位 百分比范围0 ~ 100.0 var mHeight: Float64 // 设置组件高度单位 vp当小于 0.0 时取 0.0 var swipeRightWidth: Float64 // 设置右侧布局宽度单位 vp范围0 ~ 当前设备屏幕宽度 var swipeLeftWidth: Float64 // 设置左侧布局宽度单位 vp范围0 ~ 当前设备屏幕宽度 var rightDisable: Bool // 是否禁用右侧滑动默认 false var leftDisable: Bool // 是否禁用左侧滑动默认 false var mDuration: Int32 // 设置动画持续时间默认 200 ms }对照核心实现 swipe_item_layout.cj各参数的类型、默认值与语义汇总如下参数类型默认值源码语义与取值约定surfaceViewBuilderParam (String, Int64) - Unit—内容层构建器接收(itemContent, itemId)即被滑动的表面组件swipeRightViewBuilderParam (Int64) - Unit—右侧滑动布局构建器接收itemIdswipeLeftViewBuilderParam (Int64) - Unit—左侧滑动布局构建器接收itemIditemContentLink String组件内容文本与外部状态双向同步itemIdLink Int640组件索引供构建器区分不同列表项mWidthFloat64100.0组件宽度单位百分比范围0 ~ 100.0源码在aboutToAppear中会将超过 100.0 的值钳制为 100.0mHeightFloat6490.0组件高度单位 vp特性文档约定当小于0.0时取0.0swipeRightWidthFloat64120.0右侧布局宽度单位 vp范围0 ~ 当前设备屏幕宽度swipeLeftWidthFloat64120.0左侧布局宽度单位 vp范围0 ~ 当前设备屏幕宽度rightDisableBoolfalse为true时禁用右侧滑动leftDisableBoolfalse为true时禁用左侧滑动mDurationInt32200展开/收回动画持续时间单位 ms三条关键布局约定特性文档特别给出三条推荐直接决定滑动效果是否正常显示surfaceView滑动内容组件的宽度、高度推荐与组件的mWidth、mHeight保持一致右侧滑动布局文档中称为bottomViewRight代码中对应swipeRightView的宽度推荐与swipeRightWidth保持一致左侧滑动布局文档中称为bottomViewLeft代码中对应swipeLeftView的宽度推荐与swipeLeftWidth保持一致。这样做的原因是侧滑视图是绝对定位在容器两侧的详见第四章如果其实际渲染宽度与传入的swipeXXXWidth不一致就会出现露出的操作区宽度与滑动位移量不匹配的问题。三、运行示例从零搭建一个左右侧滑动页面特性文档给出了一个完整的Entry页面示例直接在build()中放置一个SwipeItemLayout即可看到左滑删除、右滑选择的效果。仓库中的 normal_view.cj 与之完全对应import ohos.base.* import ohos.component.* import ohos.state_manage.* import ohos.state_macro_manage.* import swipeitem.* import ohos.prompt_action.* import ohos.hilog.Hilog Entry Component class NormalView { var content: String 侧滑内容子组件侧滑内容子组件侧滑内容子组件 protected override func aboutToAppear() { AppLog.info(aboutToAppear) } Builder func surfaceView(itemContent: String, itemId: Int64) { Text(itemContent).fontSize(16).width(100.percent).height(45).fontColor(Color(0x999999)).backgroundColor( Color(0xEBEBEB)).padding(left: 10.0) } Builder func swipeRightView(itemId: Int64) { Text(删除).fontSize(14).backgroundColor(0xFFFF1E38).fontColor(Color.WHITE).width(100.percent).height( 100.percent).textAlign(TextAlign.Center).onClick( { evt PromptAction.showToast( message: delete, duration: 1500, ) }) } Builder func swipeLeftView(itemId: Int64) { Text(选择).fontSize(14).backgroundColor(0x317aff).fontColor(Color.WHITE).width(100.percent).height( 100.percent).textAlign(TextAlign.Center).onClick( { evt PromptAction.showToast( message: choose, duration: 1500, ) }) } func build() { Row { Column() { ColumnSplit() { SwipeItemLayout( mWidth: 100.0, mHeight: 45.0, swipeLeftWidth: 85.0, swipeRightWidth: 85.0, surfaceView: surfaceView, swipeLeftView: this.swipeLeftView, swipeRightView: this.swipeRightView, itemContent: content, itemId: 0 ) }.height(10.percent) }.width(100.percent) }.height(100.percent) } }示例中需要重点理解的三件事三个Builder各司其职surfaceView(itemContent, itemId)内容层宽高与组件保持一致100.percent/45实现第一条布局约定swipeRightView(itemId)右侧删除按钮红色背景、白色文字点击后弹出PromptAction.showToastswipeLeftView(itemId)左侧选择按钮蓝色背景点击后弹出PromptAction.showToast。参数传入方式surfaceView: surfaceView直接传函数引用而swipeLeftView/swipeRightView使用this.显式引用两种写法在 Cangjie 中均可itemContent: content将页面状态传入Link。import 集合除swipeitem.*外还需引入ohos.base.*、ohos.component.*、ohos.state_manage.*、ohos.state_macro_manage.*状态管理、ohos.prompt_action.*Toast等基础模块。四、滑动交互的源码实现原理SwipeItemLayout的滑动能力全部由 swipe_item_layout.cj 实现核心思路可概括为三句话一个可平移的 Row 容器、三个分层子视图、一套基于 onTouch 的手势状态机。4.1 容器结构与三层视图从build()的结构看组件是一个Row容器最终通过.position(x: offsetX, y: offsetY)整体平移内部按顺序摆放三层Row() { if (!leftDisable) { Row() { this.swipeLeftView(itemId) } .width(this.swipeLeftWidth).position(x: -this.swipeLeftWidth, y: 0.0).onTouch(...) } Row() { this.surfaceView(itemContent, itemId) }.onTouch(...) if (!rightDisable) { Row() { this.swipeRightView(itemId) } .height(this.mHeight).width(this.swipeRightWidth).onTouch(...) } }.width(this.mWidth.percent).height(this.mHeight).position(x: this.offsetX, y: this.offsetY)从源码结构看左侧视图被绝对定位在x: -swipeLeftWidth即初始位于可视区域左侧之外只有容器右移offsetX 0时才会进入视野右侧视图紧跟在surfaceView之后排布初始位于可视区域右侧之外只有容器左移offsetX 0时才会进入视野因此右滑moveX 0露出左侧选择区左滑moveX 0露出右侧删除区与示例页面的按钮布局一一对应。4.2 手势判定横向优先 纵向容差surfaceView与两侧视图都注册了onTouch统一采用三阶段事件模型Down记录按下坐标sX、sYMove计算位移moveX screenX - sX、moveY screenY - sY先做方向判定——只有abs(moveX) abs(moveY)横向滑动占主导且moveY落在(-30, 30)vp 的纵向容差带内才进入侧滑逻辑从而避免与列表纵向滚动冲突Up根据松手时的位移决定展开还是收回。滑动过程中offsetX被实时更新左滑时在0 ~ -swipeRightWidth区间跟手右滑时在0 ~ swipeLeftWidth区间跟手超出边界即被钳制如offsetX -swipeRightWidth实现拖到尽头停住的效果。4.3 松手判定40 vp 阈值与回弹动画Up 事件中通过animateTo驱动收尾动画判定阈值在源码中固定为40 vp展开状态offsetX 0即左侧区露出moveX 40保持展开、moveX 0收回、moveX -40收回、moveX 0保持展开收回状态offsetX 0即右侧区露出方向相反同理。动画参数为animateTo( AnimateParam( duration: this.mDuration, // 默认 200 ms tempo: 1.0, curve: Curve.FastOutLinearIn, // 快速进入、线性退出符合侧滑手感 iterations: 1, playMode: PlayMode.Normal, onFinish: { this.rightSlideEnable true; this.leftSlideEnable true } ), { /* 依据 moveX 设置最终 offsetX */ } )动画结束后通过onFinish复位两个互斥标志位rightSlideEnable/leftSlideEnable允许下一次手势继续操作。4.4 禁用开关与手势互斥rightDisable/leftDisable是布局层与交互层双重开关为true时对应视图不再构建同时 Move 判定中对应方向的滑动手势被忽略rightSlideEnable/leftSlideEnable是运行期互斥标志当一侧视图已展开、用户反向滑动时先收回已展开的一侧置对应标志为false避免两侧操作区同时露出。4.5 参数钳制aboutToAppear 里的边界保护在 aboutToAppear 中组件会对传入参数做一次防御性校正通过getDefaultDisplaySync().width获取屏幕宽度px 转 vpswipeRightWidth/swipeLeftWidth大于等于屏幕宽度时钳制为屏幕宽度小于0.0时钳制为0.0mWidth大于100.0时钳制为100.0。这解释了特性文档中范围0 ~ 当前设备屏幕宽度范围0 ~ 100.0等取值约束的来源——即使调用方传了越界值组件也会在挂载阶段自动修正。五、实战进阶官方三个示例页面解读仓库entry模块的 page 目录 提供了三种由浅入深的用法入口页 index.cj 通过Router.push分别跳转到三个页面5.1 单条示例 NormalView即第三章的完整代码一个SwipeItemLayout直接放在ColumnSplit中用于理解组件的最小使用形态。5.2 多行列表示例 MoreListmore_list.cj 演示了组件在List中的典型用法用ForEach遍历 26 个元素的数组每个ListItem内放置一个SwipeItemLayoutitemContent传入item.toString()、itemId传入index从而让每个列表项拥有独立的滑动状态List(initialIndex: 0) { ForEach( this.arr, itemGeneratorFunc: { item: Int64, index: Int64 ListItem() { SwipeItemLayout( mWidth: 100.0, mHeight: 60.0, swipeLeftWidth: 85.0, swipeRightWidth: 85.0, surfaceView: surfaceView, swipeLeftView: this.swipeLeftView, swipeRightView: this.swipeRightView, itemContent: item.toString(), itemId: index ) } } ) }.divider(strokeWidth: 5.px, color: Color(0xd2d3cc)).width(100.percent)由于组件内部用State offsetX管理位移、用Link itemId区分条目多列表场景下各条目之间互不干扰这正是itemId参数存在的意义。5.3 全宽右侧操作区示例 LargrWidthViewlarge_width_view.cj 展示了两个高级用法swipeRightWidth: Float64(this.disWidth)将右侧操作区宽度直接设为屏幕宽度在aboutToAppear中通过getDefaultDisplaySync().width获取形成整行全宽删除面板效果leftDisable: true禁用左侧滑动只保留右侧操作说明leftDisable/rightDisable可用于按业务需要裁剪交互方向。同时该示例的右侧构建器不止一个按钮而是Image Text Blank Button的组合布局证明侧滑视图可以承载任意复杂度 UIBuilder func swipeRightView(itemId: Int64) { Image(r(app.media.trash)).backgroundColor(0xff64e3b9).width(10.percent).height(100.percent).padding(10).objectFit( ImageFit.Contain).onClick({ evt PromptAction.showToast(message: Magnifier, duration: 1500) }) Text(Delete item?).fontSize(14).height(100.percent).fontColor(Color.WHITE).backgroundColor(Color.RED).padding(5).onClick( { evt PromptAction.showToast(message: Click on surface, duration: 1500) }) Blank().backgroundColor(Color.RED) Button(Yes,Delete).backgroundColor(Color.WHITE).fontColor(0xe52626).fontSize(14).width(35.percent).height( 70.px).shape(ShapeType.Capsule).margin(right: 10.0).onClick( { event PromptAction.showToast(message: click delete, duration: 1500) }) }六、将 swipeitem 接入自有 Cangjie 工程README 提供了两种接入方式均无需修改组件源码方式一模块拷贝克隆下载项目将swipeitem模块整体拷贝到目标工程下在目标应用entry的 oh-package.json5 的dependencies字段添加本地模块依赖{ name: entry, version: 1.0.0, dependencies: { swipeitem: file:../swipeitem } }在目标应用entry/src/main/cangjie下的cjpm.toml的[dependencies]字段添加仓颉包依赖与仓库 entry 的 cjpm.toml 写法一致[dependencies] swipeitem {path ../../../../swipeitem/src/main/cangjie, version 1.0.0}在业务代码中引入并直接使用组件import swipeitem.*方式二git submodule 三方库依赖在目标工程third-party目录下以 submodule 方式引入https://gitcode.com/Cangjie-TPC/swipe-item-cj.git修改目标应用cjpm.toml[dependencies] swipeitem {path ../../../../third-party/swipe-item-cj/swipeitem/src/main/cangjie, version 1.0.0}同样通过import swipeitem.*使用。无论哪种方式cjpm.toml中path的相对基准都是entry/src/main/cangjie实际开发时请按自身目录结构调整../../层数。七、约束与验证环境根据 README 的约束与限制说明该组件在以下环境验证通过DevEco Studio NEXT Developer Beta25.0.3.906Cangjie Support Plugin 5.0.3.906Cangjie Compiler0.53.13cjnative。此外仓库内entry与swipeitem的 cjpm.toml 均声明cjc-version 0.48.2接入时建议保持编译器版本不低于该值。本项目基于 MIT License 开源可直接自由使用与二次开发当前版本v0.0.1见 CHANGELOG.md核心能力即支持左侧和右侧的滑动布局。小结SwipeItemLayout用极简的参数面3 个构建器 7 个配置项封装了复杂的侧滑交互BuilderParam让内容层与左右操作区完全由调用方定制Link打通页面数据rightDisable/leftDisable按需裁剪方向mDuration控制回弹手感而源码内部的横向手势判定、40 vp 阈值与animateTo(FastOutLinearIn)动画则保证了与系统列表滚动共存时的流畅体验。无论是单条演示、多行列表还是全宽操作面板均可参照 entry 示例 直接落地到业务代码中。赞分享UI组件移动开发OpenHarmony【免费下载链接】swipe-item-cj自定义侧滑操作UI组件项目地址https://gitcode.com/Cangjie-TPC/swipe-item-cj点击查看免费下载相关推荐swipe-item-cj 实战指南用 Cangjie 语言打造 HarmonyOS 左右侧滑动操作组件swipe item cj 实战指南用 Cangjie 语言打造 HarmonyOS 左右侧滑动操作组件 swipe item cj 是一个基于 CangjiUI组件移动开发OpenHarmonyswipe-item-cj侧滑动画实现揭秘animateTo回弹逻辑与FastOutLinearIn曲线解析swipe item cj侧滑动画实现揭秘animateTo回弹逻辑与FastOutLinearIn曲线解析 swipe item cj 是基于仓颉CangUI组件移动开发OpenHarmonyamis Slider 左右滑动容器组件JSON 配置、事件监听与源码原理详解amis Slider 左右滑动容器组件JSON 配置、事件监听与源码原理详解 导读 本文围绕 amis 前端低代码框架中的 slider 组件左右滑动容器前端低代码UI组件上一篇B站直播场控神器可编程弹幕机器人让你告别手忙脚乱下一篇Viper 异步 NetBIOS 扫描模块NextnetByPE实战指南多网段内网主机发现与网卡地址枚举创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑