64 lines
1.6 KiB
Dart
64 lines
1.6 KiB
Dart
import 'package:flutter/material.dart';
|
|
|
|
typedef VoidFutureCallBack = Future<void> Function();
|
|
|
|
class FutureTextButton extends StatefulWidget {
|
|
const FutureTextButton({
|
|
Key? key,
|
|
this.onLongPress,
|
|
this.onHover,
|
|
this.onFocusChange,
|
|
this.style,
|
|
this.focusNode,
|
|
this.autofocus = false,
|
|
this.clipBehavior = Clip.none,
|
|
required this.child,
|
|
required this.onPressed,
|
|
}) : super(key: key);
|
|
|
|
final VoidFutureCallBack? onPressed;
|
|
final VoidCallback? onLongPress;
|
|
final ValueChanged<bool>? onHover;
|
|
final ValueChanged<bool>? onFocusChange;
|
|
final ButtonStyle? style;
|
|
final Clip clipBehavior;
|
|
final FocusNode? focusNode;
|
|
final bool autofocus;
|
|
final Widget child;
|
|
|
|
@override
|
|
State<FutureTextButton> createState() => _FutureTextButtonState();
|
|
}
|
|
|
|
class _FutureTextButtonState extends State<FutureTextButton> {
|
|
bool _isBusy = false;
|
|
|
|
Future<void> onPressed() async {
|
|
if (_isBusy) return;
|
|
setState(() => _isBusy = true);
|
|
try {
|
|
await widget.onPressed?.call();
|
|
} catch (e) {
|
|
rethrow;
|
|
} finally {
|
|
if (mounted) setState(() => _isBusy = false);
|
|
}
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return TextButton(
|
|
key: widget.key,
|
|
onPressed: _isBusy || widget.onPressed == null ? null : () => onPressed(),
|
|
onLongPress: widget.onLongPress,
|
|
onHover: widget.onHover,
|
|
onFocusChange: widget.onFocusChange,
|
|
style: widget.style,
|
|
focusNode: widget.focusNode,
|
|
autofocus: widget.autofocus,
|
|
clipBehavior: widget.clipBehavior,
|
|
child: widget.child,
|
|
);
|
|
}
|
|
}
|