Flutter指针事件拦截插件pointer_interceptor_web的使用

发布于 1周前 作者 sinazl 来自 Flutter

Flutter指针事件拦截插件 pointer_interceptor_web 的使用

pointer_interceptor_webpointer_interceptor 插件的Web实现。这个插件允许你在Flutter Web应用中拦截或忽略特定区域的指针事件(如点击、触摸等),从而避免这些事件穿透到下面的HTML元素或其他Flutter组件。

使用方法

该插件是官方认可的联邦插件之一,这意味着你可以在项目中直接使用 pointer_interceptor 而无需显式地将其添加到 pubspec.yaml 文件中。不过,如果你需要直接调用此包中的API,则应将它添加到你的 pubspec.yaml 文件中。

示例代码

以下是一个完整的示例demo,展示了如何在Flutter Web应用中使用 pointer_interceptor_web 来处理不同的交互场景:

import 'dart:ui_web' as ui_web;
import 'package:flutter/material.dart';
import 'package:pointer_interceptor_platform_interface/pointer_interceptor_platform_interface.dart';
import 'package:pointer_interceptor_web/pointer_interceptor_web.dart';

const String _htmlElementViewType = '_htmlElementViewType';
const double _containerWidth = 640;
const double _containerHeight = 480;

final web.Element _htmlElement =
    (web.document.createElement('div') as web.HTMLDivElement)
      ..style.width = '100%'
      ..style.height = '100%'
      ..style.backgroundColor = '#fabada'
      ..style.cursor = 'auto'
      ..id = 'background-html-view';

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

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  [@override](/user/override)
  Widget build(BuildContext context) {
    return const MaterialApp(
      title: 'Stopping Clicks with PointerInterceptor',
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key});

  [@override](/user/override)
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  String _lastClick = 'none';

  void _clickedOn(String key) {
    setState(() {
      _lastClick = key;
    });
  }

  [@override](/user/override)
  void initState() {
    super.initState();
    ui_web.platformViewRegistry.registerViewFactory(
      _htmlElementViewType,
      (int viewId) => _htmlElement,
    );
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('PointerInterceptor demo'),
        actions: <Widget>[
          PointerInterceptorPlatform.instance.buildWidget(
            child: IconButton(
              icon: const Icon(Icons.add_alert),
              tooltip: 'AppBar Icon',
              onPressed: () {
                _clickedOn('appbar-icon');
              },
            ),
          ),
        ],
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'Last click on: $_lastClick',
              key: const Key('last-clicked'),
            ),
            Container(
              color: Colors.black,
              width: _containerWidth,
              height: _containerHeight,
              child: Stack(
                alignment: Alignment.center,
                children: <Widget>[
                  HtmlElement(
                    onClick: () {
                      _clickedOn('html-element');
                    },
                  ),
                  Row(
                    mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                    children: <Widget>[
                      ElevatedButton(
                        key: const Key('transparent-button'),
                        child: const Text('Never calls onPressed'),
                        onPressed: () {
                          _clickedOn('transparent-button');
                        },
                      ),
                      PointerInterceptorWeb().buildWidget(
                          intercepting: false,
                          child: ElevatedButton(
                            key: const Key('wrapped-transparent-button'),
                            child: const Text('Never calls onPressed transparent'),
                            onPressed: () {
                              _clickedOn('wrapped-transparent-button');
                            },
                          )),
                      PointerInterceptorPlatform.instance.buildWidget(
                        child: ElevatedButton(
                          key: const Key('clickable-button'),
                          child: const Text('Works As Expected'),
                          onPressed: () {
                            _clickedOn('clickable-button');
                          },
                        ),
                      ),
                    ],
                  ),
                ],
              ),
            ),
          ],
        ),
      ),
      floatingActionButton: Row(
        mainAxisAlignment: MainAxisAlignment.end,
        children: <Widget>[
          PointerInterceptorPlatform.instance.buildWidget(
            child: FloatingActionButton(
              child: const Icon(Icons.navigation),
              onPressed: () {
                _clickedOn('fab-1');
              },
            ),
          ),
        ],
      ),
      drawer: Drawer(
        child: PointerInterceptorPlatform.instance.buildWidget(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              ListTile(
                title: const Text('Item 1'),
                onTap: () {
                  _clickedOn('drawer-item-1');
                },
              ),
              ListTile(
                title: const Text('Item 2'),
                onTap: () {
                  _clickedOn('drawer-item-2');
                },
              ),
            ],
          ),
        ),
      ),
    );
  }
}

class HtmlElement extends StatelessWidget {
  const HtmlElement({super.key, required this.onClick});

  final VoidCallback onClick;

  [@override](/user/override)
  Widget build(BuildContext context) {
    _htmlElement.addEventListener(
      'click',
      (JSAny? _) {
        onClick();
      }.toJS,
    );

    return const HtmlElementView(
      viewType: _htmlElementViewType,
    );
  }
}

更多关于Flutter指针事件拦截插件pointer_interceptor_web的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter指针事件拦截插件pointer_interceptor_web的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是如何在Flutter Web项目中使用pointer_interceptor_web插件来拦截指针事件的代码案例。这个插件允许你在Flutter Web应用中拦截和处理鼠标和触摸事件,从而可以对这些事件进行自定义处理。

步骤 1: 添加依赖

首先,你需要在pubspec.yaml文件中添加pointer_interceptor_web依赖:

dependencies:
  flutter:
    sdk: flutter
  pointer_interceptor_web: ^最新版本号 # 请替换为实际最新版本号

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

步骤 2: 导入插件并拦截指针事件

接下来,在你的Flutter应用中导入pointer_interceptor_web插件,并在需要的地方拦截指针事件。以下是一个完整的示例:

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: PointerInterceptorExample(),
    );
  }
}

class PointerInterceptorExample extends StatefulWidget {
  @override
  _PointerInterceptorExampleState createState() => _PointerInterceptorExampleState();
}

class _PointerInterceptorExampleState extends State<PointerInterceptorExample> {
  PointerInterceptorController? _controller;

  @override
  void initState() {
    super.initState();
    // 初始化PointerInterceptorController
    _controller = PointerInterceptorController()
      ..addPointerDownListener((PointerDownEvent event) {
        // 在这里处理指针按下事件
        print('Pointer Down Intercepted: ${event.position}');
      })
      ..addPointerMoveEventListener((PointerMoveEvent event) {
        // 在这里处理指针移动事件
        print('Pointer Move Intercepted: ${event.position}');
      })
      ..addPointerUpListener((PointerUpEvent event) {
        // 在这里处理指针抬起事件
        print('Pointer Up Intercepted: ${event.position}');
      });
  }

  @override
  void dispose() {
    // 释放资源
    _controller?.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Pointer Interceptor Example'),
      ),
      body: Stack(
        children: [
          // 使用PointerInterceptorWidget来拦截指针事件
          PointerInterceptorWidget(
            controller: _controller!,
            child: Container(
              color: Colors.transparent, // 这个容器可以是任何你想要拦截事件的Widget
            ),
          ),
          // 其他内容
          Center(
            child: Text(
              'Move your pointer around to see intercepted events in the console.',
              style: TextStyle(fontSize: 24),
            ),
          ),
        ],
      ),
    );
  }
}

解释

  1. 依赖添加:首先在pubspec.yaml中添加pointer_interceptor_web依赖。
  2. 导入插件:在Dart文件中导入pointer_interceptor_web
  3. 初始化控制器:在initState方法中初始化PointerInterceptorController,并添加指针事件监听器。
  4. 释放资源:在dispose方法中释放控制器资源。
  5. 使用PointerInterceptorWidget:在Widget树中使用PointerInterceptorWidget来包裹你想要拦截事件的Widget,并将控制器传递给它。

这样,你就可以在Flutter Web应用中拦截和处理指针事件了。你可以根据需要修改监听器中的逻辑来处理不同的事件。

回到顶部