Кнопка с асинхронным действием в Flutter
Сохранение на сервер или долгая операция
не должны давать нажать кнопку дважды.
В State хранят флаг busy
и поле Future или просто ждут
завершения в async-методе.
Пока busy истинно, у
ElevatedButton
ставят onPressed: null или меняют
child на маленький
CircularProgressIndicator
с ограничением размера через SizedBox:
import 'package:flutter/material.dart';
void main() {
runApp(const MaterialApp(home: AsyncButtonPage()));
}
class AsyncButtonPage extends StatefulWidget {
const AsyncButtonPage({super.key});
@override
State<AsyncButtonPage> createState() => _AsyncButtonPageState();
}
class _AsyncButtonPageState extends State<AsyncButtonPage> {
bool busy = false;
String status = 'Tap Send';
Future<void> send() async {
setState(() {
busy = true;
status = 'Sending...';
});
await Future<void>.delayed(const Duration(seconds: 2));
if (!mounted) return;
setState(() {
busy = false;
status = 'Sent';
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Async button')),
body: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(status),
const SizedBox(height: 16),
ElevatedButton(
onPressed: busy ? null : send,
child: busy
? const SizedBox(
width: 22,
height: 22,
child: CircularProgressIndicator(strokeWidth: 2),
)
: const Text('Send'),
),
],
),
),
);
}
}
Сделайте кнопку «Sync» с задержкой
4 секунды. Во время работы показывайте
только индикатор; после успеха текст
'Synced'.