SingleTapDetector

A Flutter widget that prevents multiple rapid taps by implementing debounce protection. Perfect for preventing multiple navigation screens from opening on rapid user taps.

Features

  • 🚫 Prevents multiple rapid taps with configurable debounce duration
  • 🔄 Auto-resets after debounce period
  • 🛡️ Safe disposal handling with mounted checks
  • Lightweight and performant
  • 🎯 Easy to use - just wrap any widget

Problem Solved

Have you ever experienced this issue?

  • User taps a button/card multiple times quickly
  • Multiple screens open in the navigation stack
  • User has to press back button multiple times to return

SingleTapDetector solves this by preventing multiple rapid taps and ensuring only one action is executed.

Installation

Add this to your package's pubspec.yaml file:

dependencies:
  single_tap_detector: ^1.0.1

Usage

Basic Usage

import 'package:single_tap_detector/single_tap_detector.dart';

SingleTapDetector(
  onTap: () {
    // Your navigation or action here
    Navigator.push(context, MaterialPageRoute(
      builder: (context) => NextScreen(),
    ));
  },
  child: Card(
    child: ListTile(
      title: Text('Tap me!'),
    ),
  ),
)

With Custom Debounce Duration

SingleTapDetector(
  debounceDuration: Duration(milliseconds: 500), // 0.5 seconds
  onTap: () {
    // Your action here
  },
  child: ElevatedButton(
    onPressed: null, // Disable default onPressed
    child: Text('Upload'),
  ),
)

Real-World Example

// Before: Multiple screens could open
InkWell(
  onTap: () => Navigator.push(context, MaterialPageRoute(
    builder: (context) => ReportScreen(),
  )),
  child: ReportCard(),
)

// After: Only one screen opens
SingleTapDetector(
  onTap: () => Navigator.push(context, MaterialPageRoute(
    builder: (context) => ReportScreen(),
  )),
  child: ReportCard(),
)

API Reference

SingleTapDetector

A widget that prevents multiple rapid taps.

Properties

  • child (Widget, required): The widget to wrap with tap protection
  • onTap (VoidCallback, required): The callback to execute when tapped
  • debounceDuration (Duration, optional): How long to block subsequent taps (default: 1 second)

Example

SingleTapDetector(
  debounceDuration: Duration(milliseconds: 1000),
  onTap: () {
    print('Tapped!');
  },
  child: Container(
    width: 100,
    height: 100,
    color: Colors.blue,
    child: Center(child: Text('Tap Me')),
  ),
)

How It Works

  1. First tap: Executes the callback and sets protection flag
  2. Subsequent taps: Blocked until debounce duration expires
  3. After duration: Protection resets, ready for next tap
  4. Widget disposal: Safely handles widget lifecycle

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

This project is licensed under the MIT License - see the LICENSE file for details.