diff --git a/packages/mix/lib/src/widgets/widget_state/pressable_widget.dart b/packages/mix/lib/src/widgets/widget_state/pressable_widget.dart index e113b801b..ba37929f7 100644 --- a/packages/mix/lib/src/widgets/widget_state/pressable_widget.dart +++ b/packages/mix/lib/src/widgets/widget_state/pressable_widget.dart @@ -1,3 +1,5 @@ +import 'dart:async'; + import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; @@ -277,15 +279,30 @@ abstract class _MixStateWidgetBuilderState setState(fn); } - Future unpressAfterDelay(int initialPressCount) async { - final delay = widget.unpressDelay; + Timer? _timer; - if (delay != Duration.zero) { - await Future.delayed(delay); + @override + void dispose() { + _timer?.cancel(); + super.dispose(); + } + + void unpressAfterDelay(int initialPressCount) { + void unpressCallback() { + if (_isPressed && _pressCount == initialPressCount) { + updateState(() => _isPressed = false); + } } - if (_isPressed && _pressCount == initialPressCount) { - updateState(() => _isPressed = false); + _timer?.cancel(); + _timer = null; + + final delay = widget.unpressDelay; + + if (delay != Duration.zero) { + _timer = Timer(delay, unpressCallback); + } else { + unpressCallback(); } } diff --git a/packages/mix/test/src/widgets/pressable/pressable_widget_test.dart b/packages/mix/test/src/widgets/pressable/pressable_widget_test.dart index 5015eb66b..5ea8f43e6 100644 --- a/packages/mix/test/src/widgets/pressable/pressable_widget_test.dart +++ b/packages/mix/test/src/widgets/pressable/pressable_widget_test.dart @@ -131,6 +131,31 @@ void main() { }); }); + testWidgets('Pressable cancel timer on dispose', (WidgetTester tester) async { + var wasPressed = false; + + await tester.pumpWidget( + MaterialApp( + home: Scaffold( + body: Pressable( + autofocus: true, + unpressDelay: const Duration(minutes: 1), + onPress: () { + wasPressed = !wasPressed; + }, + child: const Text('Tap me'), + ), + ), + ), + ); + + await tester.sendKeyEvent(LogicalKeyboardKey.enter); + expect(wasPressed, isTrue); + + await tester.sendKeyEvent(LogicalKeyboardKey.enter); + expect(wasPressed, isFalse); + }); + group('PressableBox', () { testWidgets( 'must be clickable when enable is setted to true',