tap_debouncer 0.0.3 copy "tap_debouncer: ^0.0.3" to clipboard
tap_debouncer: ^0.0.3 copied to clipboard

outdated

Tap debounce simplifying widget

debouncer #

Tap debounce simplifying widget

Instruction #

Assume your code with some button look like this:

//...
child: RaisedButton(
  color: Colors.blue,
  disabledColor: Colors.grey,
  onPressed: () async => await someLongOperation(), // your tap handler
  child: const Text('Short'),
  );
//...

and you do not want user to be able to press the button again several times and start other someLongOperation functions. Example is a Navigator pop function - it can take a few hundred of millis to navigate and user can press the button several times, and that will lead to undesired pop several screens back instead of one.

Wrap this code to Debouncer and move RaisedButton onPressed contents to Debouncer onTap:

//...
child: Debouncer(
  onTap: () async => await someLongOperation(), // your tap handler moved here
  builder: (BuildContext context, DebouncerOnTap onTap) {
    return RaisedButton(
      color: Colors.blue,
      disabledColor: Colors.grey,
      onPressed: onTap,  // It is just onTap from builder callback
      child: const Text('Short'),
    );
  },
),
//...

Debouncer will disable the RaisedButton by setting onPressed to null while onTap is being executed.

You can add optional delay to be sure that the button is disabled some time after someOperation is called.

//...
onTap: () async {
    someOperation();
    
    await Future<void>.delayed(
      const Duration(milliseconds: 1000),
      () {},
    );
},
//...

See example application for details:

Example of button disabled after tap