Flutter:如何响应交互事件?

1,602 阅读2分钟

目录传送门:《Flutter快速上手指南》先导篇

思考一个问题,在 Flutter 中如何处理点击、长按等手势交互呢 🤔 ?

事实上,Flutter 提供了多种处理手势交互的方案,本篇文章介绍一种比较通用和全能的方案: GestureDetector

使用 GestureDetector 可以获得各种类型的点击事件回调,因此你可以创建出能够处理各种点击事件的 Widget 来。

1.GestureDetector 常用手势

现在,看看 GestureDetector 有些什么常用的交互事件吧:

  • onTap:单击

  • onDoubleTap:双击

  • onLongPress:长按

  • onTapUp:手指抬起来时

  • onTapDown:手指触碰屏幕时

  • onTapCancel:点击没有完成

  • onVerticalDragDown:手指刚接触屏幕时,随后开始垂直方向上的拖动

  • onVerticalDragStart:垂直方向上的拖动开始时

  • onVerticalDragUpdate:垂直方向上的拖动更新时

  • onVerticalDragEnd:垂直方向上的拖动结束时

  • onVerticalDragCancel:垂直拖动没有完成

  • onHorizontallyDragDown:手指刚接触屏幕时,随后开始水平方向上的拖动

  • onHorizontallyDragStart:水平方向上的拖动开始时

  • onHorizontallyDragUpdate:水平方向上的拖动更新时

  • onHorizontallyDragEnd:水平方向上的拖动结束时

  • onHorizontallyDragCancel:水平拖动没有完成

  • onScaleStart:开始缩放时,初始 scale 为 1.0

  • onScaleUpdate:缩放更新时

  • onScaleEnd:缩放结束

  • onPanDown:手指触摸屏幕时

  • onPanUpdate:手指移动时

  • onPanEnd:滑动结束时

2.如何使用 GestureDetector

  1. 使用 GestureDetector 创建一个可交互的 Widget。

    class TapBox extends StatefulWidget {
    
      final bool active;
      // 定义一个函数,外界传入后可被调用
      final ValueChanged<bool> onChanged;
    
      TapBox({Key key, this.active, this.onChanged}) : super(key: key);
    
      @override
      State<StatefulWidget> createState() {
        return _TabBox();
      }
    }
    
    class _TabBox extends State<TapBox> {
      bool _highlight = false;
    
      void _handleTapDown(TapDownDetails details) {
        setState(() {
          _highlight = true;
        });
      }
    
      void _handleTapUp(TapUpDetails details) {
        setState(() {
          _highlight = false;
        });
      }
    
      void _handleTapCancel() {
        setState(() {
          _highlight = false;
        });
      }
    
      void _handleTap() {
        // 通过 widget 可以获得其成员变量
        widget.onChanged(!widget.active);
      }
    
      Widget build(BuildContext context) {
        // 把你的 Widget 使用 GestureDetector 包裹📦起来
        return GestureDetector(
          // 处理按下手势
          onTapDown: _handleTapDown,
          // 处理抬起手势
          onTapUp: _handleTapUp,
          // 处理点击手势
          onTap: _handleTap,
          // 处理取消手势
          onTapCancel: _handleTapCancel,
          child: Container(
            child: Center(
              child: Text(widget.active ? 'Active' : 'Inactive',
                  style: TextStyle(fontSize: 32.0, color: Colors.white)),
            ),
            width: 200.0,
            height: 200.0,
            decoration: BoxDecoration(
              color: widget.active ? Colors.lightGreen[700] : Colors.grey[600],
              border: _highlight
                  ? Border.all(
                      color: Colors.teal[700],
                      width: 10.0,
                    )
                  : null,
            ),
          ),
        );
      }
    }
    

    你看,GestureDetector 也是一个 Widget,通过使用它来包裹目标 Widget,就使得目标 Widget 具有处理事件的能力。

  2. 使用这个 Widget。

    class ParentWidget extends StatefulWidget {
      @override
      State<StatefulWidget> createState() {
        return _ParentWidget();
      }
    }
    
    class _ParentWidget extends State<ParentWidget> {
      bool _active = false;
    
      void _handleTapBoxChanged(bool newValue) {
        setState(() {
          _active = newValue;
        });
      }
    
      @override
      Widget build(BuildContext context) {
        return Container(
          child: TapBox(
            active: _active,
            // 传入函数
            onChanged: _handleTapBoxChanged,
          ),
        );
      }
    }
    

    运行效果:

目录传送门:《Flutter快速上手指南》先导篇

如何找到我?

传送门:CoorChice 的主页

传送门:CoorChice 的 Github