Flutter手势检测插件positioned_tap_detector_2的使用

Flutter手势检测插件positioned_tap_detector_2的使用

Flutter widget允许接收点击回调,并附带点击位置。它支持 onTaponDoubleTaponLongPress 手势。每个回调函数都带有一个 TapPosition 对象,该对象提供了全局和相对触摸位置。要调整双击之间允许的最大时间延迟,可以指定一个额外的 doubleTapDelay 参数:

PositionedTapDetector(
  onTap: (position) => _printTap('Single tap', position),
  onDoubleTap: (position) => _printTap('Double tap', position),
  onLongPress: (position) => _printTap('Long press', position),
  doubleTapDelay: Duration(milliseconds: 500),
  child: ...,
)

void _printTap(String gesture, TapPosition position) => 
    print('$gesture: ${position.global}, ${position.relative ?? '-'}');
PositionedTapDetector demo

控制器

如果你需要在 widget 树中包装另一个 GestureDetector,可以传递一个额外的 PositionedTapController 参数,并在其相关手势发生时调用其回调方法:

final _controller = PositionedTapController();

Widget build(BuildContext context) {
  // ...
    child: PositionedTapDetector2(
      // ...
      controller: _controller,
      child: GestureDetector(
        onTap: _handleTap,
        onTapDown: _controller.onTapDown,
        onLongPress: _controller.onLongPress,
        behavior: ...,
        child: ...,
      ),
    ),
}

void _handleTap() {
  // ...
  _controller.onTap();
}

缺点

如果在 PositionedTapDetector2 下方的 widget 树中有另一个 GestureDetector 并且也指定了 onDoubleTap 参数,则 PositionedTapDetector2 将不会调用 onDoubleTap 回调。由于 Flutter 框架在检测到双击时不会调用其 onTapDown 回调,因此 positioned detector 无法接收到点击位置并因此无法检测双击手势。

示例代码

以下是完整的示例代码:

import 'package:flutter/material.dart';
import 'package:positioned_tap_detector_2/positioned_tap_detector_2.dart';

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

class MyApp extends StatefulWidget {
  @override
  MyAppState createState() => new MyAppState();
}

class MyAppState extends State<MyApp> {
  String _gesture = "";
  TapPosition _position = TapPosition(Offset.zero, Offset.zero);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              PositionedTapDetector2(
                onTap: _onTap,
                onDoubleTap: _onDoubleTap,
                onLongPress: _onLongPress,
                child: Container(
                  width: 160.0,
                  height: 160.0,
                  color: Colors.redAccent,
                ),
              ),
              Padding(
                padding: EdgeInsets.only(top: 16.0),
                child: Text("Gesture: $_gesture\n"
                    "Global: ${_formatOffset(_position.global)}\n"
                    "Relative: ${_formatOffset(_position.relative!)}"),
              ),
            ],
          ),
        ),
      ),
    );
  }

  void _onTap(TapPosition position) => _updateState('single tap', position);

  void _onDoubleTap(TapPosition position) =>
      _updateState('double tap', position);

  void _onLongPress(TapPosition position) =>
      _updateState('long press', position);

  void _updateState(String gesture, TapPosition position) {
    setState(() {
      _gesture = gesture;
      _position = position;
    });
  }

  String _formatOffset(Offset offset) =>
      "${offset.dx.toStringAsFixed(1)}, ${offset.dy.toStringAsFixed(1)}";
}

更多关于Flutter手势检测插件positioned_tap_detector_2的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter手势检测插件positioned_tap_detector_2的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是如何在Flutter中使用positioned_tap_detector_2插件进行手势检测的示例代码。这个插件允许你检测屏幕上特定位置的点击事件。

首先,确保你已经在pubspec.yaml文件中添加了positioned_tap_detector_2依赖项:

dependencies:
  flutter:
    sdk: flutter
  positioned_tap_detector_2: ^x.y.z  # 请将x.y.z替换为最新版本号

然后运行flutter pub get来安装依赖。

接下来,你可以在你的Flutter应用中使用PositionedTapDetector来检测手势。以下是一个完整的示例:

import 'package:flutter/material.dart';
import 'package:positioned_tap_detector_2/positioned_tap_detector_2.dart';

void main() {
  runApp(MyApp());
}

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

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

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Positioned Tap Detector Example'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            // 使用PositionedTapDetector包裹一个容器
            PositionedTapDetector(
              onTapDown: (details) {
                print('Tapped down at position: ${details.globalPosition}');
              },
              onTapUp: (details) {
                print('Tapped up at position: ${details.globalPosition}');
              },
              onTap: (details) {
                print('Tapped at position: ${details.globalPosition}');
              },
              onDoubleTap: (details) {
                print('Double tapped at position: ${details.globalPosition}');
              },
              onLongPress: (details) {
                print('Long pressed at position: ${details.globalPosition}');
              },
              child: Container(
                width: 200,
                height: 200,
                color: Colors.lightblue,
                child: Center(
                  child: Text(
                    'Tap me!',
                    style: TextStyle(color: Colors.white, fontSize: 24),
                  ),
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

在这个示例中,我们创建了一个简单的Flutter应用,其中包含一个中心对齐的Container。这个ContainerPositionedTapDetector包裹,该组件可以监听多种手势事件,包括:

  • onTapDown:当触摸开始时触发。
  • onTapUp:当触摸结束时触发。
  • onTap:当完成一次点击(触摸开始和结束在同一个位置)时触发。
  • onDoubleTap:当双击时触发。
  • onLongPress:当长按时触发。

每次触发这些事件时,都会在控制台中打印出相应的位置信息。

你可以根据需要调整PositionedTapDetector的参数和事件处理逻辑,以满足你的应用需求。

回到顶部