Foti Dim
Foti Dim

Reputation: 1371

Flutter IgnorePointer for 2 fingers

I am trying to ignore multi-finger touches (2-finger specifically) on a Button by wrapping it with IgnorePointer() like so:

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."),
        ));
  }
}

I want isSingleTouch to be true when the user uses one finger but false when he uses two fingers. Is there any way to get the number of fingers and if it is 2 then make the button fail the hit test?

Upvotes: 2

Views: 1918

Answers (1)

Sanjay Sharma
Sanjay Sharma

Reputation: 4035

Please check the below example to detect two figure touch. You can modify it as per your requirement.

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);

Upvotes: 1

Related Questions