Flutter_點(diǎn)擊事件和手勢

Flutter_點(diǎn)擊事件和手勢

Flutter中的手勢系統(tǒng)有兩個(gè)獨(dú)立的層扒秸。第一層具有原始指針事件骚露,其描述屏幕上指針(例如蕴掏,觸摸障般,鼠標(biāo)和測針)的位置和移動(dòng)。第二層具有手勢盛杰,其描述由一個(gè)或多個(gè)指針移動(dòng)組成的語義動(dòng)作挽荡。

指針

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

  • PointerDownEvent 指針已在特定位置與屏幕聯(lián)系即供。
  • PointerMoveEvent 指針已從屏幕上的一個(gè)位置移動(dòng)到另一個(gè)位置徐伐。
  • PointerUpEvent 指針已停止接觸屏幕。
  • PointerCancelEvent 來自此指針的輸入不再指向此應(yīng)用募狂。

代碼

class MyApp extends StatelessWidget {
  // This widget is the root of your application.

  @override
  Widget build(BuildContext context) {
    return Listener(
      onPointerDown: (down) {
        print("onPointerDownEvent");
      },
      onPointerMove: (move) {
        print("onPointerMove");
      },
      onPointerUp: (up) {
        print("onPointerUp");
      },
      onPointerHover: (hover) {
        print("onPointerHover");
      },
      onPointerExit: (exit) {
        print("onPointerExit");
      },
      onPointerCancel: (cancle){
        print("onPointerCancel");
      },
      onPointerEnter: (enter) {
        print("onPointerEnter");
      },
      child: Center(
        child: Text(
          "test",
          textDirection: TextDirection.ltr,
        ),
      ),
    );
  }
}
在指針向下時(shí)办素,框架會對您的應(yīng)用程序執(zhí)行命中測試角雷,以確定指針與屏幕接觸的位置存在哪個(gè)小部件。然后將指針向下事件(以及該指針的后續(xù)事件)調(diào)度到命中測試找到的最內(nèi)部窗口小部件性穿。從那里勺三,事件在樹上冒泡,并被分派到從最里面的小部件到樹的根的路徑上的所有小部件需曾。沒有用于取消或停止指針事件進(jìn)一步調(diào)度的機(jī)制吗坚。

要直接從窗口小部件圖層偵聽指針事件,請使用 <b>Listener</b> 窗口小部件呆万。但是商源,通常,請考慮使用手勢(如下所述)谋减。

Listener監(jiān)聽屬性

behavior → HitTestBehavior
在命中測試期間如何表現(xiàn)牡彻。

onPointerCancel → PointerCancelEventListener
當(dāng)觸發(fā)onPointerDown的指針的輸入不再指向此接收器時(shí)調(diào)用。

onPointerDown → PointerDownEventListener
當(dāng)指針與屏幕(用于觸摸指針)接觸時(shí)調(diào)用出爹,或者在此窗口小部件的位置按下其按鈕(用于鼠標(biāo)指針)庄吼。

onPointerEnter → PointerEnterEventListener
當(dāng)指針進(jìn)入此窗口小部件的區(qū)域時(shí)調(diào)用。

onPointerExit → PointerExitEventListener
當(dāng)指針離開此窗口小部件的區(qū)域時(shí)調(diào)用严就。

onPointerHover → PointerHoverEventListener
當(dāng)未觸發(fā)onPointerDown的指針改變位置時(shí)調(diào)用总寻。

onPointerMove → PointerMoveEventListener
當(dāng)觸發(fā)onPointerDown的指針改變位置時(shí)調(diào)用。

onPointerUp → PointerUpEventListener
當(dāng)觸發(fā)onPointerDown的指針不再與屏幕接觸時(shí)調(diào)用梢为。

手勢

手勢表示從多個(gè)單獨(dú)指針事件識別的語義動(dòng)作(例如渐行,點(diǎn)擊,拖動(dòng)和縮放)铸董,甚至可能是多個(gè)單獨(dú)的指針祟印。手勢可以分派多個(gè)事件,對應(yīng)于手勢的生命周期(例如袒炉,拖動(dòng)開始,拖動(dòng)更新和拖動(dòng)結(jié)束):

  • 點(diǎn)擊

    • onTapDown 可能導(dǎo)致點(diǎn)擊的指針已在特定位置與屏幕聯(lián)系樊零。
    • onTapUp 將觸發(fā)敲擊的指針已停止在特定位置接觸屏幕我磁。
    • onTap 已經(jīng)發(fā)生了敲擊。
    • onTapCancel之前觸發(fā)的指針onTapDown不會導(dǎo)致點(diǎn)擊驻襟。
  • 雙擊

    • onDoubleTap 用戶快速連續(xù)兩次在同一位置點(diǎn)擊屏幕夺艰。
  • 長按

    • onLongPress 指針長時(shí)間保持與相同位置的屏幕接觸。
  • 垂直拖動(dòng)

    • onVerticalDragStart 指針已接觸屏幕沉衣,可能會開始垂直移動(dòng)郁副。
    • onVerticalDragUpdate 與屏幕接觸并垂直移動(dòng)的指針在垂直方向上移動(dòng)。
      onVerticalDragEnd 之前與屏幕接觸并垂直移動(dòng)的指針不再與屏幕接觸豌习,并且在停止接觸屏幕時(shí)以特定速度移動(dòng)存谎。
  • 水平拖動(dòng)

    • onHorizontalDragStart 指針已接觸屏幕拔疚,可能開始水平移動(dòng)。
    • onHorizontalDragUpdate 與屏幕接觸并水平移動(dòng)的指針在水平方向上移動(dòng)既荚。
    • onHorizontalDragEnd 先前與屏幕接觸并且水平移動(dòng)的指針不再與屏幕接觸稚失,并且當(dāng)它停止接觸屏幕時(shí)以特定速度移動(dòng)。
    • onPanStart指針已接觸屏幕恰聘,可能開始水平或垂直移動(dòng)句各。如果 - onHorizontalDragStart或onVerticalDragStart設(shè)置了此回調(diào),則會導(dǎo)致崩潰 晴叨。
    • onPanUpdate指針與屏幕接觸并沿垂直或水平方向移動(dòng)凿宾。如果 - onHorizontalDragUpdate或onVerticalDragUpdate設(shè)置了此回調(diào),則會導(dǎo)致崩潰 兼蕊。
    • onPanEnd之前與屏幕接觸的指針不再與屏幕接觸初厚,并且在停止接觸屏幕時(shí)以特定速度移動(dòng)。如果onHorizontalDragEnd或 - onVerticalDragEnd設(shè)置了此回調(diào)遍略,則會導(dǎo)致崩潰 惧所。

要從小部件圖層中聆聽手勢,請使用 <b>GestureDetector</b>绪杏。

代碼

class MyApp extends StatelessWidget {
  // This widget is the root of your application.

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: () {
        print("onPointerDownEvent");
      },
      onDoubleTap: () {
        print("onDoubleTap");
      },
      onForcePressEnd: (end) {
        print("onForcePressEnd");
      },
      onForcePressPeak: (peak) {
        print("onForcePressPeak");
      },
      onForcePressStart: (start) {
        print("onForcePressStart");
      },
      onForcePressUpdate: (update) {
        print("onForcePressUpdate");
      },
      onHorizontalDragCancel: () {
        print("onHorizontalDragCancel");
      },
      onHorizontalDragDown: (down) {
        print("onHorizontalDragDown");
      },
      onHorizontalDragEnd: (end) {
        print("onHorizontalDragEnd");
      },
      onHorizontalDragStart: (start) {
        print("onHorizontalDragStart");
      },
      onHorizontalDragUpdate: (update) {
        print("onHorizontalDragUpdate");
      },
      onLongPressDragStart: (start) {
        print("onLongPressDragStart");
      },
      onLongPressDragUp: (up) {
        print("onLongPressDragUp");
      },
      onLongPressDragUpdate: (update) {
        print("onLongPressDragUpdate");
      },
      //監(jiān)聽更多方法可以在這里添加
      child: Center(
        child: Text(
          "test",
          textDirection: TextDirection.ltr,
        ),
      ),
    );
  }
}

GestureDetector監(jiān)聽屬性

behavior → HitTestBehavior
在命中測試期間下愈,此手勢檢測器應(yīng)如何表現(xiàn)

child → Widget
樹中此小部件下方的小部件。

dragStartBehavior → DragStartBehavior
確定處理拖動(dòng)開始行為的方式蕾久。

excludeFromSemantics → bool
是否從語義樹中排除這些手勢势似。例如,用于顯示工具提示的長按手勢被排除僧著,因?yàn)楣ぞ咛崾颈旧碇苯影谡Z義樹中履因,因此具有顯示它的手勢將導(dǎo)致信息的重復(fù)。

onDoubleTap → GestureTapCallback
用戶快速連續(xù)兩次在同一位置點(diǎn)擊屏幕盹愚。

onForcePressEnd → GestureForcePressEndCallback
指針不再與屏幕接觸栅迄。

onForcePressPeak → GestureForcePressPeakCallback
指針與屏幕接觸并以最大力按下。力量至少是 ForcePressGestureRecognizer.peakPressure皆怕。

onForcePressStart → GestureForcePressStartCallback
指針與屏幕接觸毅舆,并用足夠的力按壓以啟動(dòng)壓力。力量至少是 ForcePressGestureRecognizer.startPressure愈腾。

onForcePressUpdate → GestureForcePressUpdateCallback
指針與屏幕接觸憋活,之前已經(jīng)通過了 ForcePressGestureRecognizer.startPressure,并且要么在屏幕的平面上移動(dòng)虱黄,要么用不同的力按壓屏幕悦即,要么同時(shí)按兩個(gè)屏幕。

onHorizontalDragCancel → GestureDragCancelCallback
先前觸發(fā)onHorizo??ntalDragDown的指針未完成。

onHorizontalDragDown → GestureDragDownCallback
指針已接觸屏幕辜梳,可能開始水平移動(dòng)粱甫。

onHorizontalDragEnd → GestureDragEndCallback
前與屏幕接觸并且水平移動(dòng)的指針不再與屏幕接觸,并且當(dāng)它停止接觸屏幕時(shí)以特定速度移動(dòng)冗美。

onHorizontalDragStart → GestureDragStartCallback
指針已接觸屏幕并開始水平移動(dòng)魔种。

onHorizontalDragUpdate → GestureDragUpdateCallback
與屏幕接觸并水平移動(dòng)的指針在水平方向上移動(dòng)。

onLongPress → GestureLongPressCallback
指針長時(shí)間保持與相同位置的屏幕接觸粉洼。

onLongPressDragStart → GestureLongPressDragStartCallback
指針長時(shí)間保持與相同位置的屏幕接觸节预。

onLongPressDragUp → GestureLongPressDragUpCallback
無論長按后是否拖動(dòng)指針,觸發(fā)長按的指針都停止接觸屏幕属韧。

onLongPressDragUpdate → GestureLongPressDragUpdateCallback
長按后安拟,指針已被拖動(dòng)。

onLongPressUp → GestureLongPressUpCallback
觸發(fā)長按的指針已停止接觸屏幕宵喂。

onPanCancel → GestureDragCancelCallback
先前觸發(fā)onPanDown的指針未完成糠赦。

onPanDown → GestureDragDownCallback
指針已接觸屏幕并可能開始移動(dòng)。

onPanEnd → GestureDragEndCallback
先前與屏幕接觸并移動(dòng)的指針不再與屏幕接觸锅棕,并且當(dāng)它停止接觸屏幕時(shí)以特定速度移動(dòng)拙泽。

onPanStart → GestureDragStartCallback
指針已經(jīng)接觸屏幕并開始移動(dòng)。

onPanUpdate → GestureDragUpdateCallback
與屏幕接觸并移動(dòng)的指針再次移動(dòng)裸燎。

onScaleEnd → GestureScaleEndCallback
指針不再與屏幕接觸顾瞻。

onScaleStart → GestureScaleStartCallback
與屏幕接觸的指針已建立焦點(diǎn),初始比例為1.0德绿。

onScaleUpdate → GestureScaleUpdateCallback
與屏幕接觸的指針表示新的焦點(diǎn)和/或比例荷荤。

onTap → GestureTapCallback
已經(jīng)發(fā)生了敲擊

onTapCancel → GestureTapCancelCallback
先前觸發(fā)onTapDown的指針不會導(dǎo)致點(diǎn)擊。

onTapDown → GestureTapDownCallback
可能導(dǎo)致點(diǎn)擊的指針已在特定位置與屏幕聯(lián)系移稳。

onTapUp → GestureTapUpCallback
將觸發(fā)敲擊的指針已停止在特定位置接觸屏幕蕴纳。

onVerticalDragCancel → GestureDragCancelCallback
先前觸發(fā)onVerticalDragDown的指針未完成。

onVerticalDragDown → GestureDragDownCallback
指針已接觸屏幕个粱,可能會開始垂直移動(dòng)古毛。

onVerticalDragEnd → GestureDragEndCallback
之前與屏幕接觸并垂直移動(dòng)的指針不再與屏幕接觸,并且在停止接觸屏幕時(shí)以特定速度移動(dòng)都许。

onVerticalDragStart → GestureDragStartCallback
指針已接觸屏幕并已開始垂直移動(dòng)稻薇。

onVerticalDragUpdate → GestureDragUpdateCallback
與屏幕接觸并垂直移動(dòng)的指針在垂直方向上移動(dòng)。
如果您正在使用Material Components梭稚,那么這些小部件中的許多小部件已經(jīng)響應(yīng)了輕擊或手勢颖低。例如絮吵, IconButton和 FlatButton 響應(yīng)按下(輕擊)弧烤,并 ListView 響應(yīng)滑動(dòng)以觸發(fā)滾動(dòng)。如果您沒有使用這些小部件,但想要點(diǎn)擊“墨水濺”效果暇昂,則可以使用 InkWell莺戒。

手勢消歧

在屏幕上的給定位置處,可能存在多個(gè)手勢檢測器急波。所有這些手勢檢測器在它們經(jīng)過并且嘗試識別特定手勢時(shí)監(jiān)聽指針事件流从铲。該 GestureDetector 插件決定嘗試在此基礎(chǔ)上的回調(diào)都是非空識別哪些手勢。

當(dāng)對于屏幕上的給定指針存在多于一個(gè)手勢識別器時(shí)澄暮,框架通過使每個(gè)識別器加入手勢場來消除用戶想要的手勢名段。手勢競技場使用以下規(guī)則確定哪個(gè)手勢獲勝:

在任何時(shí)候,識別器都可以宣告失敗并離開競技場泣懊。如果競技場中只剩下一個(gè)識別器伸辟,那么識別器就是贏家。

在任何時(shí)候馍刮,識別器都可以聲明勝利信夫,這會導(dǎo)致勝利并且所有剩余的識別器都會丟失。

例如卡啰,當(dāng)消除水平和垂直拖動(dòng)的歧義時(shí)静稻,兩個(gè)識別器在接收指針向下事件時(shí)進(jìn)入競技場。識別器觀察指針移動(dòng)事件匈辱。如果用戶水平移動(dòng)指針超過一定數(shù)量的邏輯像素振湾,則水平識別器將聲明勝利并且手勢將被解釋為水平拖動(dòng)。類似地梅誓,如果用戶垂直移動(dòng)超過一定數(shù)量的邏輯像素恰梢,則垂直識別器將聲明勝利。

當(dāng)僅存在水平(或垂直)拖動(dòng)識別器時(shí)梗掰,手勢競技場是有益的嵌言。在這種情況下,競技場中將只有一個(gè)識別器及穗,并且水平拖動(dòng)將立即被識別摧茴,這意味著水平移動(dòng)的第一個(gè)像素可以被視為拖動(dòng),并且用戶將不需要等待進(jìn)一步的手勢消歧埂陆。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末苛白,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子焚虱,更是在濱河造成了極大的恐慌购裙,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,123評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件鹃栽,死亡現(xiàn)場離奇詭異躏率,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,031評論 2 384
  • 文/潘曉璐 我一進(jìn)店門薇芝,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蓬抄,“玉大人,你說我怎么就攤上這事夯到∪络裕” “怎么了?”我有些...
    開封第一講書人閱讀 156,723評論 0 345
  • 文/不壞的土叔 我叫張陵耍贾,是天一觀的道長阅爽。 經(jīng)常有香客問我,道長荐开,這世上最難降的妖魔是什么优床? 我笑而不...
    開封第一講書人閱讀 56,357評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮誓焦,結(jié)果婚禮上胆敞,老公的妹妹穿的比我還像新娘。我一直安慰自己杂伟,他們只是感情好移层,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,412評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著赫粥,像睡著了一般观话。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上越平,一...
    開封第一講書人閱讀 49,760評論 1 289
  • 那天频蛔,我揣著相機(jī)與錄音,去河邊找鬼秦叛。 笑死晦溪,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的挣跋。 我是一名探鬼主播三圆,決...
    沈念sama閱讀 38,904評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼避咆!你這毒婦竟也來了舟肉?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,672評論 0 266
  • 序言:老撾萬榮一對情侶失蹤查库,失蹤者是張志新(化名)和其女友劉穎路媚,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體樊销,經(jīng)...
    沈念sama閱讀 44,118評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡整慎,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,456評論 2 325
  • 正文 我和宋清朗相戀三年适荣,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片院领。...
    茶點(diǎn)故事閱讀 38,599評論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖够吩,靈堂內(nèi)的尸體忽然破棺而出比然,到底是詐尸還是另有隱情,我是刑警寧澤周循,帶...
    沈念sama閱讀 34,264評論 4 328
  • 正文 年R本政府宣布强法,位于F島的核電站,受9級特大地震影響湾笛,放射性物質(zhì)發(fā)生泄漏饮怯。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,857評論 3 312
  • 文/蒙蒙 一嚎研、第九天 我趴在偏房一處隱蔽的房頂上張望蓖墅。 院中可真熱鬧,春花似錦临扮、人聲如沸论矾。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,731評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽贪壳。三九已至,卻和暖如春蚜退,著一層夾襖步出監(jiān)牢的瞬間闰靴,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,956評論 1 264
  • 我被黑心中介騙來泰國打工钻注, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留蚂且,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,286評論 2 360
  • 正文 我出身青樓幅恋,卻偏偏與公主長得像膘掰,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子佳遣,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,465評論 2 348

推薦閱讀更多精彩內(nèi)容