flutter onPressed onTap等手勢檢測及觸摸事件處理


我怎么給 Flutter 的 widget 添加一個點擊監聽者?

在 iOS 中,你給一個 view 添加 GestureRecognizer 來處理點擊事件。在 Flutter 中,有兩種方法來添加點擊監聽者:

  1. 如果 widget 本身支持事件監測,直接傳遞給它一個函數,並在這個函數里實現響應方法。例如,RaisedButton widget 擁有一個 RaisedButton 參數:

    @override
    Widget build(BuildContext context) {
      return RaisedButton(
        onPressed: () {
          print("click");
        },
        child: Text("Button"),
      );
    }
  2. 如果 widget 本身不支持事件監測,則在外面包裹一個 GestureDetector,並給它的 onTap 屬性傳遞一個函數:
    class SampleApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: Center(
            child: GestureDetector(
              child: FlutterLogo(
                size: 200.0,
              ),
              onTap: () {
                print("tap");
              },
            ),
          ),
        );
      }
    }

    我怎么處理 widget 上的其他手勢?

    使用 GestureDetector 你可以監聽更廣闊范圍內的手勢,比如:

    • Tapping
      • onTapDown — 在特定位置輕觸手勢接觸了屏幕。
      • onTapUp — 在特定位置產生了一個輕觸手勢,並停止接觸屏幕。
      • onTap — 產生了一個輕觸手勢。
      • onTapCancel — 觸發了 onTapDown 但沒能觸發 tap。
    • Double tapping
      • onDoubleTap — 用戶在同一個位置快速點擊了兩下屏幕。
    • Long pressing
      • onLongPress — 用戶在同一個位置長時間接觸屏幕。
    • Vertical dragging
      • onVerticalDragStart — 接觸了屏幕,並且可能會垂直移動。
      • onVerticalDragUpdate — 接觸了屏幕,並繼續在垂直方向移動。
      • onVerticalDragEnd — 之前接觸了屏幕並垂直移動,並在停止接觸屏幕前以某個垂直的速度移動。
    • Horizontal dragging
      • onHorizontalDragStart — 接觸了屏幕,並且可能會水平移動。
      • onHorizontalDragUpdate — 接觸了屏幕,並繼續在水平方向移動。
      • onHorizontalDragEnd — 之前接觸屏幕並水平移動的觸摸點與屏幕分離。

    下面這個例子展示了一個 GestureDetector 是如何在雙擊時旋轉 Flutter 的 logo 的: 

  3. import 'package:flutter/material.dart';
    
    void main() {
      runApp(SampleApp());
    }
    
    class SampleApp extends StatelessWidget {
      // This widget is the root of your application.
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Sample App',
          theme: ThemeData(
            primarySwatch: Colors.blue,
          ),
          home: AnimateApp(),
        );
      }
    }
    
    class AnimateApp extends StatefulWidget {
      @override
      State<StatefulWidget> createState() {
        return _AnimateAppState();
      }
    }
    
    class _AnimateAppState extends State<AnimateApp>
        with SingleTickerProviderStateMixin {
      AnimationController controller;
      Animation<double> animation;
      CurvedAnimation curve;
    
      @override
      void initState() {
        super.initState();
        // 創建 AnimationController 對象
        controller = AnimationController(
            vsync: this, duration: const Duration(milliseconds: 2000));
        curve = CurvedAnimation(parent: controller, curve: Curves.easeIn);
        // 通過 Tween 對象 創建 Animation 對象
        animation = Tween(begin: 50.0, end: 200.0).animate(controller)
          ..addListener(() {
            // 注意:這句不能少,否則 widget 不會重繪,也就看不到動畫效果
            setState(() {});
          });
        // 執行動畫
        controller.forward();
      }
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
            title: 'AnimateApp',
            theme: ThemeData(primaryColor: Colors.blue),
            home: Scaffold(
                appBar: AppBar(
                  title: Text('AnimateApp'),
                ),
                body: Center(
                  child: GestureDetector(
                    child: RotationTransition(
                        turns: curve,
                        child: FlutterLogo(
                          size: 200.0,
                        )),
                    onDoubleTap: () {
                      if (controller.isCompleted) {
                        controller.reverse();
                      } else {
                        controller.forward();
                      }
                    },
                  ),
                )));
      }
    
      @override
      void dispose() {
        // 資源釋放
        controller.dispose();
        super.dispose();
      }
    }

     


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM