Flutter 通过 Widget 来处理手势事件

在前面讲按钮的时候,你会发现按钮有 onPressed 来响应点击事件,但是如果我让你去监听 Text 的点击事件,你会发现 Text 根本没有类似按钮的 onPressed 属性,那么如何去监听一个 Text 的点击事件呢?

那就需要使用专门处理手势事件的 Widget 来嵌套 Text,在 Flutter 中,手势事件识别也是通过 Widget 来实现的,通过这个,你也能更加明白 Everything is a Widget。

Flutter 手势事件的分类

手势事件在 Flutter 中分为两层:

  1. 第一层是原始的 pointer events(指针事件)
    它描述了屏幕上指针(例如,触摸,鼠标和触控笔)的位置和移动。例如:PointerDownEvent、PointerUpEvent 、PointerMoveEvent 、PointerCancelEvent 等。
    为了监听 pointer events,请使用 Listener Widget,但一般建议使用 GestureDetector Widget,就是下面要介绍的。
  2. 第二层是可以对原始的事件识别成不同的手势
    第二层是对第一层原始 pointer event 事件进行识别后的手势,例如:单击、双击、长按、拖动等。
    为了识别不同的手势,请使用 GestureDetector Widget。

下来介绍 GestureDetector 的使用。

Flutter 手势识别的 Widget —— GestureDetector

GestureDetector 是用于检测手势的 Widget。

GestureDetector 快速上手

GestureDetector 的使用很简单,只要用 GestureDetector 嵌套要检测手势的 Widget 就行,然后在 GestureDetector 里实现想要监听的手势的方法就行。

例如,想要检测 Text 的点击事件,就可以这么用:

  1. GestureDetector(
  2. child: Text('Hello Flutter'),
  3. onTap: (){
  4. print('tab Text');
  5. },
  6. )

GestureDetector 在一个页面使用的完整 Demo 为:

  1. import 'package:flutter/cupertino.dart';
  2. import 'package:flutter/material.dart';
  3. void main() => runApp(GestureDetectorWidget());
  4. class GestureDetectorWidget extends StatelessWidget {
  5. @override
  6. Widget build(BuildContext context) {
  7. return MaterialApp(
  8. title: "Flutter Demo",
  9. theme: ThemeData(
  10. primaryColor: Colors.blue,
  11. ),
  12. home: Scaffold(
  13. appBar: AppBar(title: Text("Flutter 手势识别Widget")),
  14. body: GestureDetector(
  15. child: Text('手势识别'),
  16. onTap: (){
  17. print('点击');
  18. },
  19. onDoubleTap: (){
  20. print('双击');
  21. },
  22. onLongPress: (){
  23. print('长按');
  24. },
  25. onHorizontalDragStart: (DragStartDetails details){
  26. print('水平滑动');
  27. },
  28. ),
  29. ),
  30. );
  31. }
  32. }

GestureDetector 的构造函数及参数说明

为了知道 GestureDetector 支持哪些手势,我们可以看一下 GestureDetector 的构造函数:

  1. class GestureDetector extends StatelessWidget {
  2. GestureDetector({
  3. Key key,
  4. this.child,
  5. this.onTapDown,
  6. this.onTapUp,
  7. this.onTap,
  8. this.onTapCancel,
  9. this.onDoubleTap,
  10. this.onLongPress,
  11. this.onLongPressUp,
  12. this.onLongPressDragStart,
  13. this.onLongPressDragUpdate,
  14. this.onLongPressDragUp,
  15. this.onVerticalDragDown,
  16. this.onVerticalDragStart,
  17. this.onVerticalDragUpdate,
  18. this.onVerticalDragEnd,
  19. this.onVerticalDragCancel,
  20. this.onHorizontalDragDown,
  21. this.onHorizontalDragStart,
  22. this.onHorizontalDragUpdate,
  23. this.onHorizontalDragEnd,
  24. this.onHorizontalDragCancel,
  25. this.onForcePressStart,
  26. this.onForcePressPeak,
  27. this.onForcePressUpdate,
  28. this.onForcePressEnd,
  29. this.onPanDown,
  30. this.onPanStart,
  31. this.onPanUpdate,
  32. this.onPanEnd,
  33. this.onPanCancel,
  34. this.onScaleStart,
  35. this.onScaleUpdate,
  36. this.onScaleEnd,
  37. this.behavior,
  38. this.excludeFromSemantics = false,
  39. this.dragStartBehavior = DragStartBehavior.down,
  40. })
  41. ...
  42. }

通过看 GestureDetector 构造函数的参数,就可以知道 GestureDetector 支持哪些手势。

参数名字 参数类型 意义 必选 or 可选
key Key Widget 的标识 可选
child Widget 要检测手势事件的 Widget 可选
onTapDown GestureTapDownCallback 手指触摸屏幕时产生 onTapDown 事件 可选
onTapUp GestureTapDownCallback 手指离开屏幕时产生 onTapUp 事件,之后便会触发 onTap 事件 可选
onTap GestureTapCallback 点击事件 可选
onTapCancel GestureTapCancelCallback 当触发 onTapDown 之后,取消点击,则会触发 onTapCancel,后面的 onTapDown 和 onTapUp 都不会在触发 可选
onDoubleTap GestureTapCallback 双击事件 可选
onLongPress GestureLongPressCallback 长按屏幕时触发,当监听了 onLongPress 事件时,则不能监听 onLongPressDragStart、onLongPressDragUpdate、onLongPressDragUp 可选
onLongPressUp GestureLongPressUpCallback 长按屏幕,手指离开屏幕时触发,当监听了 onLongPressUp 事件时,则不能监听 onLongPressDragStart、onLongPressDragUpdate、onLongPressDragUp 可选
onLongPressDragStart GestureLongPressDragStartCallback 长按屏幕,并准备开始拖动时触发,当监听了 onLongPressDragStart 事件时,则不能监听 onLongPress、onLongPressUp 可选
onLongPressDragUpdate GestureLongPressDragUpdateCallback 长按屏幕后并拖动时触发,当监听了 onLongPressDragUpdate 事件时,则不能监听 onLongPress、onLongPressUp 可选
onLongPressDragUp GestureLongPressDragUpCallback 长按屏幕拖动,手指离开屏幕时触发,当监听了 onLongPressDragUp 事件时,则不能监听 onLongPress、onLongPressUp 可选
onVerticalDragDown GestureDragDownCallback 手指接触屏幕,并且可能会开始垂直移动时触发 可选
onVerticalDragStart GestureDragStartCallback 手指接触屏幕,并且已经开始垂直移动时触发 可选
onVerticalDragUpdate GestureDragUpdateCallback 手指接触屏幕,并且垂直移动时触发 可选
onVerticalDragEnd GestureDragEndCallback 手指接触屏幕垂直移动,然后手指离开屏幕时触发 可选
onVerticalDragCancel GestureDragCancelCallback 当 onVerticalDragDown 没有完成时就会触发 onVerticalDragCancel 可选
onHorizontalDragDown GestureDragDownCallback 手指接触屏幕,并且可能会开始水平移动时触发 可选
onHorizontalDragStart GestureDragStartCallback 手指接触屏幕,并且已经开始水平移动时触发 可选
onHorizontalDragUpdate GestureDragUpdateCallback 手指接触屏幕,并且水平移动时触发 可选
onHorizontalDragEnd GestureDragEndCallback 手指接触屏幕水平移动,然后手指离开屏幕时触发 可选
onHorizontalDragCancel GestureDragCancelCallback 当 onHorizontalDragDown 没有完成时就会触发 onHorizontalDragCancel 可选
onForcePressStart GestureForcePressStartCallback 手指与屏幕接触,并且当有足够的压力时才会触发
注意,这个事件仅在具有压力检测屏幕的设备上触发。
可选
onForcePressPeak GestureForcePressPeakCallback 手指与屏幕接触,并且当有压力达到最大时触发
注意,这个事件仅在具有压力检测屏幕的设备上触发。
可选
onForcePressUpdate GestureForcePressUpdateCallback 手指与屏幕接触,有足够的压力并在屏幕上移动时触发
注意,这个事件仅在具有压力检测屏幕的设备上触发。
可选
onForcePressEnd GestureForcePressEndCallback 手指与屏幕分开时触发
注意,这个事件仅在具有压力检测屏幕的设备上触发。
可选
onPanDown GestureDragDownCallback 手指与屏幕接触,并且可能开始移动时触发 可选
onPanStart GestureDragStartCallback 手指与屏幕接触,并且开始移动时触发 可选
onPanUpdate GestureDragUpdateCallback 手指在屏幕上移动时触发 可选
onPanEnd GestureDragEndCallback 手指离开屏幕时触发 可选
onPanCancel GestureDragCancelCallback 当 onPanDown 没有完成时触发 onPanCancel 可选
onScaleStart GestureTapDownCallback 手指与屏幕接触,并且即将有缩放操作时触发,初始值为 1.0 可选
onScaleUpdate GestureTapDownCallback 手指与屏幕接触,并且有缩放操作时触发 可选
onScaleEnd GestureTapDownCallback onScaleStart 之后,手指离开屏幕时触发 可选
behavior HitTestBehavior 在命中测试期间,此手势检测器应如何表现。 可选
excludeFromSemantics bool 是否从语义树中排除这些手势。因为 Widget 可选
dragStartBehavior DragStartBehavior 确定处理拖动开始行为的方式。 可选

参考

【1】Flutter 实战
【2】Flutter 中文文档
【3】Flutter 完全手册