Flutter 中 手势

77 阅读3分钟

在 Flutter 中,手势(Gestures)是与用户交互的核心部分。Flutter 提供了丰富的手势检测和处理机制,使开发者能够轻松实现各种手势操作,如点击、双击、长按、拖动、缩放等。下面详细介绍 Flutter 中的手势处理,并提供相关示例代码。

手势识别器

Flutter 提供了多种手势识别器,包括:

  • GestureDetector
  • InkWell
  • GestureRecognizer

1. GestureDetector

GestureDetector 是最基本的手势识别器,用于检测各种手势,如点击、双击、长按、拖动、缩放等。

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'GestureDetector Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  String _message = "No Gesture detected";

  void _updateMessage(String message) {
    setState(() {
      _message = message;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('GestureDetector Demo'),
      ),
      body: Center(
        child: GestureDetector(
          onTap: () => _updateMessage("Tap"),
          onDoubleTap: () => _updateMessage("Double Tap"),
          onLongPress: () => _updateMessage("Long Press"),
          onPanUpdate: (details) => _updateMessage("Pan Update: ${details.localPosition}"),
          child: Container(
            color: Colors.blue,
            width: 200,
            height: 200,
            alignment: Alignment.center,
            child: Text(
              _message,
              style: TextStyle(color: Colors.white, fontSize: 16),
              textAlign: TextAlign.center,
            ),
          ),
        ),
      ),
    );
  }
}

2. InkWell

InkWell 是一种带有水波纹效果的手势识别器,常用于实现具有材质设计风格的按钮和其他可点击元素。

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'InkWell Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatelessWidget {
  void _showMessage(BuildContext context, String message) {
    ScaffoldMessenger.of(context).showSnackBar(
      SnackBar(content: Text(message)),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('InkWell Demo'),
      ),
      body: Center(
        child: InkWell(
          onTap: () => _showMessage(context, "Tap"),
          onDoubleTap: () => _showMessage(context, "Double Tap"),
          onLongPress: () => _showMessage(context, "Long Press"),
          child: Container(
            color: Colors.blue,
            width: 200,
            height: 200,
            alignment: Alignment.center,
            child: Text(
              "Tap Me",
              style: TextStyle(color: Colors.white, fontSize: 16),
              textAlign: TextAlign.center,
            ),
          ),
        ),
      ),
    );
  }
}

3. 自定义手势识别器

GestureRecognizer 是一个基类,用于创建自定义手势识别器。通常需要继承并实现自定义手势逻辑。

以下是一个简单的示例,演示如何创建一个自定义的双击手势识别器:

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Custom GestureRecognizer Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  String _message = "No Gesture detected";

  void _updateMessage(String message) {
    setState(() {
      _message = message;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Custom GestureRecognizer Demo'),
      ),
      body: Center(
        child: RawGestureDetector(
          gestures: {
            MyDoubleTapGestureRecognizer: GestureRecognizerFactoryWithHandlers<MyDoubleTapGestureRecognizer>(
              () => MyDoubleTapGestureRecognizer(),
              (MyDoubleTapGestureRecognizer instance) {
                instance.onDoubleTap = () => _updateMessage("Double Tap");
              },
            ),
          },
          child: Container(
            color: Colors.blue,
            width: 200,
            height: 200,
            alignment: Alignment.center,
            child: Text(
              _message,
              style: TextStyle(color: Colors.white, fontSize: 16),
              textAlign: TextAlign.center,
            ),
          ),
        ),
      ),
    );
  }
}

class MyDoubleTapGestureRecognizer extends OneSequenceGestureRecognizer {
  VoidCallback? onDoubleTap;

  @override
  void addAllowedPointer(PointerEvent event) {
    startTrackingPointer(event.pointer);
  }

  @override
  void handleEvent(PointerEvent event) {
    if (event is PointerDownEvent) {
      onDoubleTap?.call();
    }
  }

  @override
  String get debugDescription => 'myDoubleTap';

  @override
  void didStopTrackingLastPointer(int pointer) {}
}

解释

  1. GestureDetector:检测常见手势,如点击、双击、长按、拖动等。
  2. InkWell:带有水波纹效果的手势检测,适用于实现材质设计风格的可点击元素。
  3. GestureRecognizer:基类,用于创建自定义手势识别器。

总结

Flutter 提供了强大的手势处理能力,使开发者能够轻松实现各种交互操作。从基本的点击、双击、长按,到复杂的自定义手势,Flutter 的手势识别器能够满足各种需求。通过结合使用 GestureDetectorInkWell 和自定义手势识别器,开发者可以创建出丰富而灵活的用户交互体验。上述示例代码展示了如何在实际应用中使用这些手势识别器,帮助你快速上手和实现自定义的手势处理。