Flutter 手勢(shì)

2020-08-27 14:46 更新

介紹

本文檔介紹了如何在Flutter中監(jiān)聽并響應(yīng)手勢(shì)(點(diǎn)擊、拖動(dòng)和縮放)。

Flutter中的手勢(shì)系統(tǒng)有兩個(gè)獨(dú)立的層。第一層有原始指針(pointer)事件,它描述了屏幕上指針(例如,觸摸,鼠標(biāo)和觸控筆)的位置和移動(dòng)。 第二層有手勢(shì),描述由一個(gè)或多個(gè)指針移動(dòng)組成的語義動(dòng)作。


Pointers

指針(Pointer)代表用戶與設(shè)備屏幕交互的原始數(shù)據(jù)。有四種類型的指針事

  • PointerDownEvent 指針接觸到屏幕的特定位置
  • PointerMoveEvent 指針從屏幕上的一個(gè)位置移動(dòng)到另一個(gè)位置
  • PointerUpEvent 指針停止接觸屏幕
  • PointerCancelEvent 指針的輸入事件不再針對(duì)此應(yīng)用(事件取消)

在指針按下時(shí),框架對(duì)您的應(yīng)用程序執(zhí)行_命中測(cè)試_,以確定指針與屏幕相接的位置存在哪些widget。 指針按下事件(以及該指針的后續(xù)事件)然后被分發(fā)到由_命中測(cè)試_發(fā)現(xiàn)的最內(nèi)部的widget。 從那里開始,這些事件會(huì)冒泡在widget樹中向上冒泡,這些事件會(huì)從最內(nèi)部的widget被分發(fā)到到widget根的路徑上的所有小部件(譯者語:這和web中事件冒泡機(jī)制相似), 沒有機(jī)制取消或停止冒泡過程(譯者語:這和web不同,web中的時(shí)間冒泡是可以停止的)。

To listen to pointer events directly from the widgets layer, use a Listener widget. However, generally, consider using gestures (as discussed below) instead. 要直接從widget層監(jiān)聽指針事件,可以使用Listenerwidget。 但是,通常,請(qǐng)考慮使用手勢(shì)(如下所述)


手勢(shì)

手勢(shì)表示可以從多個(gè)單獨(dú)的指針事件(甚至可能是多個(gè)單獨(dú)的指針)識(shí)別的語義動(dòng)作(例如,輕敲,拖動(dòng)和縮放)。 完整的一個(gè)手勢(shì)可以分派多個(gè)事件,對(duì)應(yīng)于手勢(shì)的生命周期(例如,拖動(dòng)開始,拖動(dòng)更新和拖動(dòng)結(jié)束):

  • TaponTapDown 指針已經(jīng)在特定位置與屏幕接觸onTapUp 指針停止在特定位置與屏幕接觸onTap tap事件觸發(fā)onTapCancel 先前指針觸發(fā)的onTapDown不會(huì)在觸發(fā)tap事件
  • 雙擊onDoubleTap 用戶快速連續(xù)兩次在同一位置輕敲屏幕.
  • 長(zhǎng)按onLongPress 指針在相同位置長(zhǎng)時(shí)間保持與屏幕接觸
  • 垂直拖動(dòng)onVerticalDragStart 指針已經(jīng)與屏幕接觸并可能開始垂直移動(dòng)onVerticalDragUpdate 指針與屏幕接觸并已沿垂直方向移動(dòng).onVerticalDragEnd 先前與屏幕接觸并垂直移動(dòng)的指針不再與屏幕接觸,并且在停止接觸屏幕時(shí)以特定速度移動(dòng)
  • 水平拖動(dòng)onHorizontalDragStart 指針已經(jīng)接觸到屏幕并可能開始水平移動(dòng)onHorizontalDragUpdate 指針與屏幕接觸并已沿水平方向移動(dòng)onHorizontalDragEnd 先前與屏幕接觸并水平移動(dòng)的指針不再與屏幕接觸,并在停止接觸屏幕時(shí)以特定速度移動(dòng)

要從widget層監(jiān)聽手勢(shì),請(qǐng)使用 GestureDetector.

如果您使用的是Material Components,那么大多數(shù)widget已經(jīng)對(duì)tap或手勢(shì)做出了響應(yīng)。 例如 IconButton和 FlatButton 響應(yīng)presses(taps),ListView響應(yīng)滑動(dòng)事件觸發(fā)滾動(dòng)。 如果您不使用這些widget,但想要在點(diǎn)擊時(shí)上出現(xiàn)“墨水飛濺”效果,可以使用InkWell。


手勢(shì)消歧

在屏幕上的指定位置,可能會(huì)有多個(gè)手勢(shì)檢測(cè)器。所有這些手勢(shì)檢測(cè)器在指針事件流經(jīng)過并嘗試識(shí)別特定手勢(shì)時(shí)監(jiān)聽指針事件流。 GestureDetector widget決定是哪種手勢(shì)。

當(dāng)屏幕上給定指針有多個(gè)手勢(shì)識(shí)別器時(shí),框架通過讓每個(gè)識(shí)別器加入一個(gè)“手勢(shì)競(jìng)爭(zhēng)場(chǎng)”來確定用戶想要的手勢(shì)?!笆謩?shì)競(jìng)爭(zhēng)場(chǎng)”使用以下規(guī)則確定哪個(gè)手勢(shì)勝出

  • 在任何時(shí)候,識(shí)別者都可以宣布失敗并離開“手勢(shì)競(jìng)爭(zhēng)場(chǎng)”。如果在“競(jìng)爭(zhēng)場(chǎng)”中只剩下一個(gè)識(shí)別器,那么該識(shí)別器就是贏家
  • 在任何時(shí)候,識(shí)別者都可以宣布勝利,這會(huì)導(dǎo)致勝利,并且所有剩下的識(shí)別器都會(huì)失敗

例如,在消除水平和垂直拖動(dòng)的歧義時(shí),兩個(gè)識(shí)別器在接收到指針向下事件時(shí)進(jìn)入“手勢(shì)競(jìng)爭(zhēng)場(chǎng)”。識(shí)別器觀察指針移動(dòng)事件。 如果用戶將指針?biāo)揭苿?dòng)超過一定數(shù)量的邏輯像素,則水平識(shí)別器將聲明勝利,并且手勢(shì)將被解釋為水平拖拽。 類似地,如果用戶垂直移動(dòng)超過一定數(shù)量的邏輯像素,垂直識(shí)別器將宣布勝利。

當(dāng)只有水平(或垂直)拖動(dòng)識(shí)別器時(shí),“手勢(shì)競(jìng)爭(zhēng)場(chǎng)”是有益的。在這種情況下,“手勢(shì)競(jìng)爭(zhēng)場(chǎng)”將只有一個(gè)識(shí)別器,并且水平拖動(dòng)將被立即識(shí)別,這意味著水平移動(dòng)的第一個(gè)像素可以被視為拖動(dòng),用戶不需要等待進(jìn)一步的手勢(shì)消歧。

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

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)