首页 > 解决方案 > Flutter IgnorePointer for 2 个手指

问题描述

我试图通过像这样用 IgnorePointer() 包裹它来忽略 Button 上的多指触摸(特别是 2 指):

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      home: MyHomePage(title: '1 touch'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  bool isSingleTouch = true;

  @override
  Widget build(BuildContext context) {
    return IgnorePointer(
        ignoring: !isSingleTouch,
        child: RaisedButton(
          onPressed: () {
            print("Button Tapped");
          },
          child: Text("Tap with max 1 finger."),
        ));
  }
}

当用户使用一根手指时我想isSingleTouch是真的,但当他使用两根手指时我想是假的。有没有办法获得手指的数量,如果是 2,那么让按钮无法通过点击测试?

标签: flutterdartgesturehittest

解决方案


请检查以下示例以检测两个数字触摸。您可以根据您的要求对其进行修改。

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Swipe Demo',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Scaffold(
        body: Container(
          margin: EdgeInsets.only(top: 100),
          child: MultiTouchPage(
            backgroundColor: Colors.white,
            borderColor: Colors.amber,
            minTouches: 2,
            onTapCallback: (touchCount, correct) {
              print("Touch" + touchCount.toString());
            },
          ),
        ),
      ),
    );
  }
}

class MultiTouchGestureRecognizer extends MultiTapGestureRecognizer {
  MultiTouchGestureRecognizerCallback onMultiTap;
  var numberOfTouches = 0;
  int minNumberOfTouches = 0;

  MultiTouchGestureRecognizer() {
    super.onTapDown = (pointer, details) => this.addTouch(pointer, details);
    super.onTapUp = (pointer, details) => this.removeTouch(pointer, details);
    super.onTapCancel = (pointer) => this.cancelTouch(pointer);
    super.onTap = (pointer) => this.captureDefaultTap(pointer);
  }

  void addTouch(int pointer, TapDownDetails details) {
    this.numberOfTouches++;
  }

  void removeTouch(int pointer, TapUpDetails details) {
    if (this.numberOfTouches == this.minNumberOfTouches) {
      this.onMultiTap(numberOfTouches, true);
    } else if (this.numberOfTouches != 0) {
      this.onMultiTap(numberOfTouches, false);
    }

    this.numberOfTouches = 0;
  }

  void cancelTouch(int pointer) {
    this.numberOfTouches = 0;
  }

  void captureDefaultTap(int pointer) {}

  @override
  set onTapDown(_onTapDown) {}

  @override
  set onTapUp(_onTapUp) {}

  @override
  set onTapCancel(_onTapCancel) {}

  @override
  set onTap(_onTap) {}
}

typedef MultiTouchGestureRecognizerCallback = void Function(
    int touchCount, bool correctNumberOfTouches);


class MultiTouchPage extends StatefulWidget {
  final MultiTouchPageCallback onTapCallback;
  final int minTouches;
  final Color backgroundColor;
  final Color borderColor;


  MultiTouchPage(
      {this.backgroundColor,
        this.borderColor,
        this.minTouches,
        this.onTapCallback});
  @override
  _MultiTouchPageState createState() => _MultiTouchPageState();
}

class _MultiTouchPageState extends State<MultiTouchPage> {
  bool correctNumberOfTouches;
  int touchCount;
  @override
  Widget build(BuildContext context) {
    return RawGestureDetector(
      gestures: {
        MultiTouchGestureRecognizer:
        GestureRecognizerFactoryWithHandlers<MultiTouchGestureRecognizer>(
              () => MultiTouchGestureRecognizer(),
              (MultiTouchGestureRecognizer instance) {
            instance.minNumberOfTouches = widget.minTouches;
            instance.onMultiTap =
                (touchCount, correctNumberOfTouches,) => this.onTap(touchCount, correctNumberOfTouches);
          },
        ),
      },
      child: Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: <Widget>[
            Expanded(
              child: Container(
                padding: EdgeInsets.all(12.0),
                decoration: BoxDecoration(
                  color: widget.backgroundColor,
                  border: Border(
                    top: BorderSide(width: 1.0, color: widget.borderColor),
                    left: BorderSide(width: 1.0, color: widget.borderColor),
                    right: BorderSide(width: 1.0, color: widget.borderColor),
                    bottom: BorderSide(width: 1.0, color: widget.borderColor),
                  ),
                ),
                child: Text(
                    "Tap with " +
                        this.touchCount.toString() +
                        " finger(s).",
                    textAlign: TextAlign.center),
              ),
            ),
          ]),
    );
  }

  void onTap(int touchCount, bool correctNumberOfTouches) {
    this.correctNumberOfTouches = correctNumberOfTouches;
    setState(() {
      this.touchCount = touchCount;
    });
    print("Tapped with " + touchCount.toString() + " finger(s)");
    widget.onTapCallback(touchCount, correctNumberOfTouches);
  }

}

typedef MultiTouchPageCallback = void Function(int touchCount, bool correctNumberOfTouches);

推荐阅读