自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

HarmonyOS ArkUI之聊天列表滑動(dòng)刪除(TS)

開(kāi)發(fā) 前端 OpenHarmony
本項(xiàng)目基于ArkUI中TS擴(kuò)展的聲明式開(kāi)發(fā)范式,本文介紹列表滑動(dòng)刪除:列表中只允許滑出其中一項(xiàng),如果有打開(kāi)的項(xiàng),點(diǎn)擊或滑動(dòng)其他項(xiàng)都會(huì)關(guān)閉打開(kāi)的項(xiàng),點(diǎn)擊刪除,刷新列表界面。

[[436946]]

想了解更多內(nèi)容,請(qǐng)?jiān)L問(wèn):

51CTO和華為官方合作共建的鴻蒙技術(shù)社區(qū)

https://harmonyos.51cto.com

簡(jiǎn)介

本項(xiàng)目基于ArkUI中TS擴(kuò)展的聲明式開(kāi)發(fā)范式,關(guān)于語(yǔ)法和概念直接看官網(wǎng)官方文檔地址:

基于TS擴(kuò)展的聲明式開(kāi)發(fā)范式1、基于TS擴(kuò)展的聲明式開(kāi)發(fā)范式2

本文介紹列表滑動(dòng)刪除:

列表中只允許滑出其中一項(xiàng)

如果有打開(kāi)的項(xiàng),點(diǎn)擊或滑動(dòng)其他項(xiàng)都會(huì)關(guān)閉打開(kāi)的項(xiàng)

點(diǎn)擊刪除,刷新列表界面

ArKUI系列文章

效果演示

HarmonyOS ArkUI之聊天列表滑動(dòng)刪除(TS)-鴻蒙HarmonyOS技術(shù)社區(qū)

主要知識(shí)點(diǎn)

可滑動(dòng)的容器組件(Scroll)、觸摸事件(onTouch)

實(shí)現(xiàn)思路

我把界面精簡(jiǎn)了一下,減少代碼量,幫助更好的理解主要邏輯。

HarmonyOS ArkUI之聊天列表滑動(dòng)刪除(TS)-鴻蒙HarmonyOS技術(shù)社區(qū)

1、item布局

主要使用scroll包裹內(nèi)容,scroll設(shè)置為橫向滑動(dòng)(部分代碼)

  1. ..... 
  2. Scroll() { 
  3.       Row() { 
  4.         Text('內(nèi)容數(shù)據(jù)'
  5.           .width('100%').height(65) 
  6.  
  7.         Button() { 
  8.           Text('刪除'
  9.         } 
  10.         .width(100).height(65) 
  11.       } 
  12.  }.scrollable(ScrollDirection.Horizontal) // 設(shè)置為橫向滑動(dòng) 
  13. ..... 

2、Scroll容器

給Scroll容器綁定滑動(dòng)組件的控制器,只用到其中的一個(gè)方法:滑動(dòng)到指定位置 scrollTo

  1. scrollTo( 
  2.     value: { 
  3.     xOffset: number | string, yOffset: number | string, animation? 
  4.         : { duration: number, curve: Curve } 
  5.     } 
  6. ); 

看源碼得知可以設(shè)置動(dòng)畫(huà)時(shí)間,注意:時(shí)間目前好像不能設(shè)置300毫秒以上,往下設(shè)置可以 (部分代碼)

  1. ..... 
  2. // 初始化控制器 
  3. private scroller= new Scroller() 
  4. Scroll(scroller) { // 控制器綁定到滑動(dòng)容器中 
  5.       Row() { 
  6.         Text('內(nèi)容數(shù)據(jù)'
  7.           .width('100%').height(65) 
  8.  
  9.         Button() { 
  10.           Text('刪除'
  11.         } 
  12.         .width(100).height(65) 
  13.       } 
  14.  }.scrollable(ScrollDirection.Horizontal) 
  15.  
  16. Button() { 
  17.   Text('點(diǎn)擊回到原位')            
  18. }.onClick(()=>{ 
  19.   scroller.scrollTo({ xOffset: 0, yOffset: 0, animation: { duration: 200, curve: Curve.Linear } }) 
  20. }) 
  21. ..... 

3、設(shè)置觸摸事件

根據(jù)移動(dòng)的偏移量,判斷大于刪除布局寬度的一半則:打開(kāi)刪除布局(部分代碼)

  1. ..... 
  2. // 初始化控制器 
  3. private scroller= new Scroller() 
  4. // 按下的x軸坐標(biāo) 
  5. private downX = 0 
  6. // 刪除按鈕的寬度 
  7. private deleteWidth = 100 
  8.  
  9. Scroll(scroller) { // 控制器綁定到滑動(dòng)容器中 
  10.       Row() { 
  11.         Text('內(nèi)容數(shù)據(jù)'
  12.           .width('100%').height(65) 
  13.  
  14.         Button() { 
  15.           Text('刪除'
  16.         } 
  17.         .width(this.deleteWidth).height(65) 
  18.       } 
  19.  }.scrollable(ScrollDirection.Horizontal) 
  20. .onTouch((event: TouchEvent) => { // 觸摸事件 
  21.       // 根據(jù)觸摸類型判斷 
  22.       switch (event.type) { 
  23.         case TouchType.Down: // 觸摸按下 
  24.           // 記錄按下的x軸坐標(biāo) 
  25.           this.downX = event.touches[0].x 
  26.           break 
  27.         case TouchType.Up: // 觸摸抬起 
  28.           // 觸摸抬起,根據(jù)x軸總偏移量,判斷是否打開(kāi)刪除 
  29.           let xOffset = event.touches[0].x - this.downX 
  30.           // 滑到目標(biāo)x軸的位置 
  31.           var toxOffset = 0           
  32.           // 偏移量超過(guò)刪除按鈕一半且左滑,設(shè)置打開(kāi) 
  33.           if (Math.abs(xOffset) > vp2px(this.deleteWidth) / 2 && xOffset < 0) { 
  34.               // 刪除布局寬度 
  35.               toxOffset = vp2px(this.deleteWidth) 
  36.           } 
  37.           // 滑動(dòng)指定位置,設(shè)置動(dòng)畫(huà) 
  38.           item.scroller.scrollTo({ xOffset: toxOffset, yOffset: 0, 
  39.             animation: { duration: 300, curve: Curve.Linear } }) 
  40.           // 重置按下的x軸坐標(biāo) 
  41.           this.downX = 0 
  42.           break 
  43.       } 
  44.     }) 
  45. ..... 

4、使用列表加載

需要主要的點(diǎn):

  • 需要給每個(gè)item綁定控制器,這樣才能控制對(duì)應(yīng)的item打開(kāi)或關(guān)閉
  • 打開(kāi)的item記錄一下數(shù)據(jù),點(diǎn)擊內(nèi)容或刪除、滑動(dòng)其他item:如果有帶打開(kāi)的item,進(jìn)行關(guān)閉

以下是完整代碼,可直接粘貼運(yùn)行使用。

  1. class TestData { 
  2.   content: string 
  3.   scroller: Scroller 
  4.  
  5.   constructor(content: string, scroller: Scroller) { 
  6.     this.content = content 
  7.     this.scroller = scroller 
  8.   } 
  9.  
  10. @Entry 
  11. @Component 
  12. struct SlidingDeleteList { 
  13.   // 刪除按鈕的寬度 
  14.   private deleteWidth = 100 
  15.   // 按下的x軸坐標(biāo) 
  16.   private downX = 0 
  17.   // 已經(jīng)打開(kāi)刪除的數(shù)據(jù) 
  18.   private openDeleteData: TestData = null 
  19.   // 測(cè)試數(shù)據(jù) 
  20.   @State private listData: Array<TestData> = [ 
  21.     { content: '內(nèi)容數(shù)據(jù)1', scroller: new Scroller() }, { content: '內(nèi)容數(shù)據(jù)2', scroller: new Scroller() }, 
  22.     { content: '內(nèi)容數(shù)據(jù)3', scroller: new Scroller() }, { content: '內(nèi)容數(shù)據(jù)4', scroller: new Scroller() }, 
  23.     { content: '內(nèi)容數(shù)據(jù)5', scroller: new Scroller() }, { content: '內(nèi)容數(shù)據(jù)6', scroller: new Scroller() }, 
  24.     { content: '內(nèi)容數(shù)據(jù)7', scroller: new Scroller() }, { content: '內(nèi)容數(shù)據(jù)8', scroller: new Scroller() }, 
  25.   ] 
  26.  
  27.   @Builder CustomItem(item:TestData) { 
  28.     Scroll(item.scroller) { 
  29.       Row() { 
  30.         Text(item.content) 
  31.           .width('100%').height(65) 
  32.           .fontSize(16).textAlign(TextAlign.Center) 
  33.           .onClick(() => { 
  34.             // 如果刪除按鈕打開(kāi),關(guān)閉刪除按鈕且返回 
  35.             if (this.openDeleteData != null) { 
  36.               this.openDeleteData.scroller.scrollTo({ xOffset: 0, yOffset: 0, 
  37.                 animation: { duration: 100, curve: Curve.Linear } }) 
  38.               this.openDeleteData = null 
  39.               return 
  40.             } 
  41.             console.log('========點(diǎn)擊內(nèi)容========='
  42.           }) 
  43.  
  44.         Button() { 
  45.           Text('刪除'
  46.             .fontSize(15) 
  47.             .fontColor(Color.White) 
  48.         } 
  49.         .type(ButtonType.Normal) 
  50.         .width(this.deleteWidth).height(65) 
  51.         .backgroundColor(Color.Red) 
  52.         .onClick(() => { 
  53.           // 刪除當(dāng)前數(shù)據(jù) 
  54.           this.listData.splice(this.listData.indexOf(item), 1) 
  55.  
  56.           // 關(guān)閉刪除按鈕 
  57.           if (this.openDeleteData != null) { 
  58.             this.openDeleteData.scroller.scrollTo({ xOffset: 0, yOffset: 0, 
  59.               animation: { duration: 100, curve: Curve.Linear } }) 
  60.             this.openDeleteData = null 
  61.           } 
  62.           console.log('========點(diǎn)擊刪除========='
  63.         }) 
  64.       } 
  65.     }.scrollable(ScrollDirection.Horizontal) 
  66.     .onTouch((event: TouchEvent) => { // 觸摸事件 
  67.       // 判斷是否有打開(kāi)刪除組件,有則關(guān)閉 
  68.       if (this.openDeleteData != null && this.openDeleteData != item) { 
  69.         this.openDeleteData.scroller.scrollTo({ xOffset: 0, yOffset: 0, 
  70.           animation: { duration: 100, curve: Curve.Linear } }) 
  71.       } 
  72.  
  73.       // 根據(jù)觸摸類型判斷 
  74.       switch (event.type) { 
  75.         case TouchType.Down: // 觸摸按下 
  76.           // 記錄按下的x軸坐標(biāo) 
  77.           this.downX = event.touches[0].x 
  78.           break 
  79.         case TouchType.Up: // 觸摸抬起 
  80.           // 觸摸抬起,根據(jù)x軸總偏移量,判斷是否打開(kāi)刪除 
  81.           let xOffset = event.touches[0].x - this.downX 
  82.           // 防止消費(fèi)點(diǎn)擊事件 
  83.           if (xOffset == 0) { 
  84.             return 
  85.           } 
  86.           // 滑到x軸的位置 
  87.           var toxOffset = 0 
  88.           // 開(kāi)啟刪除的對(duì)象置為null 
  89.           this.openDeleteData = null
  90.           // 偏移量超過(guò)刪除按鈕一半且左滑,設(shè)置打開(kāi) 
  91.           if (Math.abs(xOffset) > vp2px(this.deleteWidth) / 2 && xOffset < 0) { 
  92.             // 刪除布局寬度 
  93.             toxOffset = vp2px(this.deleteWidth) 
  94.             this.openDeleteData = item 
  95.           } 
  96.           // 滑動(dòng)指定位置,設(shè)置動(dòng)畫(huà) 
  97.           item.scroller.scrollTo({ xOffset: toxOffset, yOffset: 0, 
  98.             animation: { duration: 300, curve: Curve.Linear } }) 
  99.           // 重置按下的x軸坐標(biāo) 
  100.           this.downX = 0 
  101.           break 
  102.       } 
  103.     }) 
  104.   } 
  105.  
  106.   build() { 
  107.     Column() { 
  108.       List() { 
  109.         ForEach(this.listData, item => { 
  110.           ListItem() { 
  111.             this.CustomItem(item) 
  112.           } 
  113.         }, item => item.toString()) 
  114.       }.divider({ color: '#f1efef', strokeWidth: 1 }) 
  115.     } 
  116.     .width('100%'
  117.     .height('100%'
  118.   } 

結(jié)尾

因?yàn)锳rkUI聲明式開(kāi)發(fā),是鴻蒙新出的東西,API還不是那么完善,后續(xù)跟進(jìn)官網(wǎng)更新。以下是需要優(yōu)化點(diǎn):

ArkUI中的TS沒(méi)有JS中的新出的插槽概念,要不然直接封裝成組件,提供兩個(gè)對(duì)外的接口,一個(gè)傳入內(nèi)容布局、一個(gè)操作布局,就像Android的組件庫(kù)一樣,使用者不需要知道內(nèi)部實(shí)現(xiàn)。

每天進(jìn)步一點(diǎn)點(diǎn)、需要付出努力億點(diǎn)點(diǎn)。

想了解更多內(nèi)容,請(qǐng)?jiān)L問(wèn):

51CTO和華為官方合作共建的鴻蒙技術(shù)社區(qū)

https://harmonyos.51cto.com

 

責(zé)任編輯:jianghua 來(lái)源: 鴻蒙社區(qū)
相關(guān)推薦

2021-12-01 10:02:57

鴻蒙HarmonyOS應(yīng)用

2022-08-23 16:07:02

ArkUI鴻蒙

2022-04-08 14:47:11

ArkUI列表字母索引鴻蒙

2022-08-08 19:46:26

ArkUI鴻蒙

2022-09-26 15:16:03

ArkUITS

2022-07-20 15:32:25

時(shí)鐘翻頁(yè)Text組件

2022-08-24 16:08:22

ETS鴻蒙

2014-12-31 14:52:27

SwipeMenuLiSwipeMenu

2021-11-23 10:00:55

鴻蒙HarmonyOS應(yīng)用

2022-11-21 16:15:41

ArkUI鴻蒙

2022-09-02 15:17:04

ArkUI鴻蒙

2021-12-03 09:49:59

鴻蒙HarmonyOS應(yīng)用

2021-01-08 09:55:17

鴻蒙HarmonyOS組裝列表

2023-08-24 16:42:29

Sample聊天實(shí)例應(yīng)用

2022-07-28 14:26:11

AI作詩(shī)應(yīng)用開(kāi)發(fā)

2021-11-16 09:38:10

鴻蒙HarmonyOS應(yīng)用

2021-11-19 09:48:33

鴻蒙HarmonyOS應(yīng)用

2017-03-13 10:11:28

AndroidRecyclerVie功能介紹

2020-10-30 20:54:29

微信新功能移動(dòng)應(yīng)用

2023-12-29 08:37:59

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)