組合手勢

2024-02-07 12:50 更新

組合手勢由多種單一手勢組合而成,通過在GestureGroup中使用不同的GestureMode來聲明該組合手勢的類型,支持順序識別、并行識別互斥識別三種類型。

  1. GestureGroup(mode:GestureMode, ...gesture:GestureType[])
  • mode:必選參數(shù),為GestureMode枚舉類。用于聲明該組合手勢的類型。
  • gesture:必選參數(shù),為由多個(gè)手勢組合而成的數(shù)組。用于聲明組合成該組合手勢的各個(gè)手勢。

順序識別

順序識別組合手勢對應(yīng)的GestureMode為Sequence。順序識別組合手勢將按照手勢的注冊順序識別手勢,直到所有的手勢識別成功。當(dāng)順序識別組合手勢中有一個(gè)手勢識別失敗時(shí),所有的手勢識別失敗。

以一個(gè)由長按手勢和拖動(dòng)手勢組合而成的順序手勢為例:

在一個(gè)Column組件上綁定了translate屬性,通過修改該屬性可以設(shè)置組件的位置移動(dòng)。然后在該組件上綁定LongPressGesture和PanGesture組合而成的Sequence組合手勢。當(dāng)觸發(fā)LongPressGesture時(shí),更新顯示的數(shù)字。當(dāng)長按后進(jìn)行拖動(dòng)時(shí),根據(jù)拖動(dòng)手勢的回調(diào)函數(shù),實(shí)現(xiàn)組件的拖動(dòng)。

  1. // xxx.ets
  2. @Entry
  3. @Component
  4. struct Index {
  5. @State offsetX: number = 0;
  6. @State offsetY: number = 0;
  7. @State count: number = 0;
  8. @State positionX: number = 0;
  9. @State positionY: number = 0;
  10. @State borderStyles: BorderStyle = BorderStyle.Solid
  11. build() {
  12. Column() {
  13. Text('sequence gesture\n' + 'LongPress onAction:' + this.count + '\nPanGesture offset:\nX: ' + this.offsetX + '\n' + 'Y: ' + this.offsetY)
  14. .fontSize(28)
  15. }
  16. // 綁定translate屬性可以實(shí)現(xiàn)組件的位置移動(dòng)
  17. .translate({ x: this.offsetX, y: this.offsetY, z: 0 })
  18. .height(250)
  19. .width(300)
  20. //以下組合手勢為順序識別,當(dāng)長按手勢事件未正常觸發(fā)時(shí)不會(huì)觸發(fā)拖動(dòng)手勢事件
  21. .gesture(
  22. // 聲明該組合手勢的類型為Sequence類型
  23. GestureGroup(GestureMode.Sequence,
  24. // 該組合手勢第一個(gè)觸發(fā)的手勢為長按手勢,且長按手勢可多次響應(yīng)
  25. LongPressGesture({ repeat: true })
  26. // 當(dāng)長按手勢識別成功,增加Text組件上顯示的count次數(shù)
  27. .onAction((event: GestureEvent) => {
  28. if (event.repeat) {
  29. this.count++;
  30. }
  31. console.info('LongPress onAction');
  32. })
  33. .onActionEnd(() => {
  34. console.info('LongPress end');
  35. }),
  36. // 當(dāng)長按之后進(jìn)行拖動(dòng),PanGesture手勢被觸發(fā)
  37. PanGesture()
  38. .onActionStart(() => {
  39. this.borderStyles = BorderStyle.Dashed;
  40. console.info('pan start');
  41. })
  42. // 當(dāng)該手勢被觸發(fā)時(shí),根據(jù)回調(diào)獲得拖動(dòng)的距離,修改該組件的位移距離從而實(shí)現(xiàn)組件的移動(dòng)
  43. .onActionUpdate((event: GestureEvent) => {
  44. this.offsetX = this.positionX + event.offsetX;
  45. this.offsetY = this.positionY + event.offsetY;
  46. console.info('pan update');
  47. })
  48. .onActionEnd(() => {
  49. this.positionX = this.offsetX;
  50. this.positionY = this.offsetY;
  51. this.borderStyles = BorderStyle.Solid;
  52. })
  53. )
  54. )
  55. }
  56. }

說明

拖拽事件是一種典型的順序識別組合手勢事件,由長按手勢事件和滑動(dòng)手勢事件組合而成。只有先長按達(dá)到長按手勢事件預(yù)設(shè)置的時(shí)間后進(jìn)行滑動(dòng)才會(huì)觸發(fā)拖拽事件。如果長按事件未達(dá)到或者長按后未進(jìn)行滑動(dòng),拖拽事件均識別失敗。

并行識別

并行識別組合手勢對應(yīng)的GestureMode為Parallel。并行識別組合手勢中注冊的手勢將同時(shí)進(jìn)行識別,直到所有手勢識別結(jié)束。并行識別手勢組合中的手勢進(jìn)行識別時(shí)互不影響。

以在一個(gè)Column組件上綁定點(diǎn)擊手勢和雙擊手勢組成的并行識別手勢為例,由于單擊手勢和雙擊手勢是并行識別,因此兩個(gè)手勢可以同時(shí)進(jìn)行識別,二者互不干涉。

  1. // xxx.ets
  2. @Entry
  3. @Component
  4. struct Index {
  5. @State count1: number = 0;
  6. @State count2: number = 0;
  7. build() {
  8. Column() {
  9. Text('parallel gesture\n' + 'tapGesture count is 1:' + this.count1 + '\ntapGesture count is 2:' + this.count2 + '\n')
  10. .fontSize(28)
  11. }
  12. .height(200)
  13. .width(250)
  14. // 以下組合手勢為并行并別,單擊手勢識別成功后,若在規(guī)定時(shí)間內(nèi)再次點(diǎn)擊,雙擊手勢也會(huì)識別成功
  15. .gesture(
  16. GestureGroup(GestureMode.Parallel,
  17. TapGesture({ count: 1 })
  18. .onAction(() => {
  19. this.count1++;
  20. }),
  21. TapGesture({ count: 2 })
  22. .onAction(() => {
  23. this.count2++;
  24. })
  25. )
  26. )
  27. }
  28. }

說明

當(dāng)由單擊手勢和雙擊手勢組成一個(gè)并行識別組合手勢后,在區(qū)域內(nèi)進(jìn)行點(diǎn)擊時(shí),單擊手勢和雙擊手勢將同時(shí)進(jìn)行識別。

當(dāng)只有單次點(diǎn)擊時(shí),單擊手勢識別成功,雙擊手勢識別失敗。

當(dāng)有兩次點(diǎn)擊時(shí),若兩次點(diǎn)擊相距時(shí)間在規(guī)定時(shí)間內(nèi)(默認(rèn)規(guī)定時(shí)間為300毫秒),觸發(fā)兩次單擊事件和一次雙擊事件。

當(dāng)有兩次點(diǎn)擊時(shí),若兩次點(diǎn)擊相距時(shí)間超出規(guī)定時(shí)間,觸發(fā)兩次單擊事件不觸發(fā)雙擊事件。

互斥識別

互斥識別組合手勢對應(yīng)的GestureMode為Exclusive?;コ庾R別組合手勢中注冊的手勢將同時(shí)進(jìn)行識別,若有一個(gè)手勢識別成功,則結(jié)束手勢識別,其他所有手勢識別失敗。

以在一個(gè)Column組件上綁定單擊手勢和雙擊手勢組合而成的互斥識別組合手勢為例,由于單擊手勢只需要一次點(diǎn)擊即可觸發(fā)而雙擊手勢需要兩次,每次的點(diǎn)擊事件均被單擊手勢消費(fèi)而不能積累成雙擊手勢,所以雙擊手勢無法觸發(fā)。

  1. // xxx.ets
  2. @Entry
  3. @Component
  4. struct Index {
  5. @State count1: number = 0;
  6. @State count2: number = 0;
  7. build() {
  8. Column() {
  9. Text('parallel gesture\n' + 'tapGesture count is 1:' + this.count1 + '\ntapGesture count is 2:' + this.count2 + '\n')
  10. .fontSize(28)
  11. }
  12. .height(200)
  13. .width(250)
  14. //以下組合手勢為互斥并別,單擊手勢識別成功后,雙擊手勢會(huì)識別失敗
  15. .gesture(
  16. GestureGroup(GestureMode.Exclusive,
  17. TapGesture({ count: 1 })
  18. .onAction(() => {
  19. this.count1++;
  20. }),
  21. TapGesture({ count: 2 })
  22. .onAction(() => {
  23. this.count2++;
  24. })
  25. )
  26. )
  27. }
  28. }

說明

當(dāng)由單擊手勢和雙擊手勢組成一個(gè)互斥識別組合手勢后,在區(qū)域內(nèi)進(jìn)行點(diǎn)擊時(shí),單擊手勢和雙擊手勢將同時(shí)進(jìn)行識別。

當(dāng)只有單次點(diǎn)擊時(shí),單擊手勢識別成功,雙擊手勢識別失敗。

當(dāng)有兩次點(diǎn)擊時(shí),單擊手勢在第一次點(diǎn)擊時(shí)即宣告識別成功,此時(shí)雙擊手勢已經(jīng)失敗。即使在規(guī)定時(shí)間內(nèi)進(jìn)行了第二次點(diǎn)擊,雙擊手勢事件也不會(huì)進(jìn)行響應(yīng),此時(shí)會(huì)觸發(fā)單擊手勢事件的第二次識別成功。

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號