Flutter:如何響應交互事件?

目錄傳送門:《Flutter快速上手指南》先導篇git

思考一個問題,在 Flutter 中如何處理點擊、長按等手勢交互呢 🤔 ?github

事實上,Flutter 提供了多種處理手勢交互的方案,本篇文章介紹一種比較通用和全能的方案: GestureDetectorbash

使用 GestureDetector 能夠得到各類類型的點擊事件回調,所以你能夠建立出可以處理各類點擊事件的 Widget 來。ide

1.GestureDetector 經常使用手勢

如今,看看 GestureDetector 有些什麼經常使用的交互事件吧:函數

  • onTap:單擊post

  • onDoubleTap:雙擊ui

  • onLongPress:長按this

  • onTapUp:手指擡起來時spa

  • onTapDown:手指觸碰屏幕時3d

  • 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

相關文章
相關標籤/搜索