本项目基于 ArkUI 中 TS 扩展的声明式开发范式,关于语法和概念直接看官网。
基于 TS 扩展的声明式开发范式 1:
https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ui-ts-overview-0000001192705715
基于 TS 扩展的声明式开发范式 2:
https://developer.harmonyos.com/cn/docs/documentation/doc-references/ts-framework-directory-0000001111581264
本文介绍列表滑动删除:
-
列表中只允许滑出其中一项
-
如果有打开的项,点击或滑动其他项都会关闭打开的项
-
点击删除,刷新列表界面
主要知识点
可滑动的容器组件(Scroll):
https://developer.harmonyos.com/cn/docs/documentation/doc-references/ts-container-scroll-0000001163543527
触摸事件(onTouch):
https://developer.harmonyos.com/cn/docs/documentation/doc-references/ts-universal-events-touch-0000001158261221
实现思路
我把界面精简了一下,减少代码量,帮助更好的理解主要逻辑。
①item 布局 主要使用 scroll 包裹内容,scroll 设置为横向滑动。部分代码如下:
.....
Scroll(){
Row(){
Text('内容数据')
.width('100%').height(65)
Button(){
Text('删除')
}
.width(100).height(65)
}
}.scrollable(ScrollDirection.Horizontal)//设置为横向滑动
.....
②Scroll 容器给 Scroll 容器绑定滑动组件的控制器,只用到其中的一个方法:滑动到指定位置 scrollTo。
scrollTo(
value:{
xOffset:number|string,yOffset:number|string,animation?
:{duration:number,curve:Curve}
}
);
看源码得知可以设置动画时间,注意:时间目前好像不能设置 300 毫秒以上,往下设置可以。
部分代码如下:
.....
//初始化控制器
privatescroller=newScroller()
Scroll(scroller){//控制器绑定到滑动容器中
Row(){
Text('内容数据')
.width('100%').height(65)
Button(){
Text('删除')
}
.width(100).height(65)
}
}.scrollable(ScrollDirection.Horizontal)
Button(){
Text('点击回到原位')
}.onClick(()=>{
scroller.scrollTo({xOffset:0,yOffset:0,animation:{duration:200,curve:Curve.Linear}})
})
.....
③设置触摸事件根据移动的偏移量,判断大于删除布局宽度的一半则:打开删除布局。
部分代码如下:
.....
//初始化控制器
privatescroller=newScroller()
//按下的x轴坐标
privatedownX=0
//删除按钮的宽度
privatedeleteWidth=100
Scroll(scroller){//控制器绑定到滑动容器中
Row(){
Text('内容数据')
.width('100%').height(65)
Button(){
Text('删除')
}
.width(this.deleteWidth).height(65)
}
}.scrollable(ScrollDirection.Horizontal)
.onTouch((event:TouchEvent)=>{//触摸事件
//根据触摸类型判断
switch(event.type){
caseTouchType.Down://触摸按下
//记录按下的x轴坐标
this.downX=event.touches[0].x
break
caseTouchType.Up://触摸抬起
//触摸抬起,根据x轴总偏移量,判断是否打开删除
letxOffset=event.touches[0].x-this.downX
//滑到目标x轴的位置
vartoxOffset=0
//偏移量超过删除按钮一半且左滑,设置打开
if(Math.abs(xOffset)>vp2px(this.deleteWidth)/2&&xOffset< 0){
//删除布局宽度
toxOffset=vp2px(this.deleteWidth)
}
//滑动指定位置,设置动画
item.scroller.scrollTo({xOffset:toxOffset,yOffset:0,
animation:{duration:300,curve:Curve.Linear}})
//重置按下的x轴坐标
this.downX=0
break
}
})
.....
④使用列表加载需要主要的点:
-
需要给每个 item 绑定控制器,这样才能控制对应的 item 打开或关闭
-
打开的 item 记录一下数据,点击内容或删除、滑动其他 item:如果有带打开的 item,进行关闭
以下是完整代码,可直接粘贴运行使用:
classTestData{
content:string
scroller:Scroller
constructor(content:string,scroller:Scroller){
this.content=content
this.scroller=scroller
}
}
@Entry
@Component
structSlidingDeleteList{
//删除按钮的宽度
privatedeleteWidth=100
//按下的x轴坐标
privatedownX=0
//已经打开删除的数据
privateopenDeleteData:TestData=null
//测试数据
@StateprivatelistData:Array=[
{content:'内容数据1',scroller:newScroller()},{content:'内容数据2',scroller:newScroller()},
{content:'内容数据3',scroller:newScroller()},{content:'内容数据4',scroller:newScroller()},
{content:'内容数据5',scroller:newScroller()},{content:'内容数据6',scroller:newScroller()},
{content:'内容数据7',scroller:newScroller()},{content:'内容数据8',scroller:newScroller()},
]
@BuilderCustomItem(item:TestData){
Scroll(item.scroller){
Row(){
Text(item.content)
.width('100%').height(65)
.fontSize(16).textAlign(TextAlign.Center)
.onClick(()=>{
//如果删除按钮打开,关闭删除按钮且返回
if(this.openDeleteData!=null){
this.openDeleteData.scroller.scrollTo({xOffset:0,yOffset:0,
animation:{duration:100,curve:Curve.Linear}})
this.openDeleteData=null
return
}
console.log('========点击内容=========')
})
Button(){
Text('删除')
.fontSize(15)
.fontColor(Color.White)
}
.type(ButtonType.Normal)
.width(this.deleteWidth).height(65)
.backgroundColor(Color.Red)
.onClick(()=>{
//删除当前数据
this.listData.splice(this.listData.indexOf(item),1)
//关闭删除按钮
if(this.openDeleteData!=null){
this.openDeleteData.scroller.scrollTo({xOffset:0,yOffset:0,
animation:{duration:100,curve:Curve.Linear}})
this.openDeleteData=null
}
console.log('========点击删除=========')
})
}
}.scrollable(ScrollDirection.Horizontal)
.onTouch((event:TouchEvent)=>{//触摸事件
//判断是否有打开删除组件,有则关闭
if(this.openDeleteData!=null&&this.openDeleteData!=item){
this.openDeleteData.scroller.scrollTo({xOffset:0,yOffset:0,
animation:{duration:100,curve:Curve.Linear}})
}
//根据触摸类型判断
switch(event.type){
caseTouchType.Down://触摸按下
//记录按下的x轴坐标
this.downX=event.touches[0].x
break
caseTouchType.Up://触摸抬起
//触摸抬起,根据x轴总偏移量,判断是否打开删除
letxOffset=event.touches[0].x-this.downX
//防止消费点击事件
if(xOffset==0){
return
}
//滑到x轴的位置
vartoxOffset=0
//开启删除的对象置为null
this.openDeleteData=null;
//偏移量超过删除按钮一半且左滑,设置打开
if(Math.abs(xOffset)>vp2px(this.deleteWidth)/2&&xOffset< 0){
//删除布局宽度
toxOffset=vp2px(this.deleteWidth)
this.openDeleteData=item
}
//滑动指定位置,设置动画
item.scroller.scrollTo({xOffset:toxOffset,yOffset:0,
animation:{duration:300,curve:Curve.Linear}})
//重置按下的x轴坐标
this.downX=0
break
}
})
}
build(){
Column(){
List(){
ForEach(this.listData,item=>{
ListItem(){
this.CustomItem(item)
}
},item=>item.toString())
}.divider({color:'#f1efef',strokeWidth:1})
}
.width('100%')
.height('100%')
}
}
结尾
因为 ArkUI 声明式开发,是鸿蒙新出的东西,API 还不是那么完善,后续跟进官网更新。 以下是需要优化点:ArkUI 中的 TS 没有 JS 中的新出的插槽概念,要不然直接封装成组件,提供两个对外的接口,一个传入内容布局、一个操作布局,就像 Android 的组件库一样,使用者不需要知道内部实现。 作者:梁青松
-
接口
+关注
关注
33文章
8593浏览量
151120 -
API
+关注
关注
2文章
1499浏览量
61991 -
JS
+关注
关注
0文章
78浏览量
18103 -
鸿蒙
+关注
关注
57文章
2350浏览量
42842
原文标题:在鸿蒙上实现聊天列表滑动删除功能!
文章出处:【微信号:gh_834c4b3d87fe,微信公众号:OpenHarmony技术社区】欢迎添加关注!文章转载请注明出处。
发布评论请先 登录
相关推荐
评论