本項目基于 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&&xOffset0){
//刪除布局寬度
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&&xOffset0){
//刪除布局寬度
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文章
8650瀏覽量
151409 -
API
+關注
關注
2文章
1505瀏覽量
62174 -
JS
+關注
關注
0文章
78瀏覽量
18127 -
鴻蒙
+關注
關注
57文章
2371瀏覽量
42910
原文標題:在鴻蒙上實現聊天列表滑動刪除功能!
文章出處:【微信號:gh_834c4b3d87fe,微信公眾號:OpenHarmony技術社區】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論