[Flutter]処理中と成功のモーダルを二つ続けて出す方法
チンムーです。 SIerでFlutterを使ってスマホアプリを開発しているエンジニアです。
Flutterでスマホアプリを開発する際、何かしら処理が発生している待ち時間に、「①処理中を表すモーダル」と「②処理が完了したことを表すモーダル」を二つ連続で出したいことがあると思うので、実装例を紹介します。
イメージ
①処理中モーダルには、処理中を表すぐるぐるとLoadigの文字を表示し、②完了モーダルにはSuccess!の文字とモーダルを閉じるボタンを表示するようにします。
流れとしては、画面のボタンを押す>①表示>3秒後に①が消えて②表示
①処理中モーダル
showLoadingModalという名前でメソッドを作成
void showLoadingModal(BuildContext context) {
showDialog<void>(
context: context,
barrierDismissible: false,
builder: (BuildContext context) {
return WillPopScope(
onWillPop: () async => false,
child: AlertDialog(
content: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: const [
CircularProgressIndicator(),
SizedBox(width: 10),
Text('Loading'),
],
),
),
);
},
);
}
②成功モーダル
処理中モーダルが消えたあとに表示するshowSuccessModal
ユーザーがCloseボタンを押すと消える
void showSuccessModal(BuildContext context) {
showDialog<void>(
context: context,
barrierDismissible: false,
builder: (BuildContext context) {
return AlertDialog(
title: const Text('Success!'),
actions: <Widget>[
TextButton(
child: const Text('Close'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
}
全体像
buttonと表示されたElevatedButtonを押すと、まずはshowLoadingModalを呼び出し。await Future.delayed(const Duration(seconds: 5));で5秒経過したら、Navigator.of(context).pop();でshowLoadingModalを消し、showSuccessModal(context);で自動的に成功モーダルを出します。
import 'package:flutter/material.dart';
class MyWidget extends StatelessWidget {
const MyWidget({Key? key}) : super(key: key);
void showLoadingModal(BuildContext context) {
showDialog<void>(
context: context,
barrierDismissible: false,
builder: (BuildContext context) {
return WillPopScope(
onWillPop: () async => false,
child: AlertDialog(
content: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: const [
CircularProgressIndicator(),
SizedBox(width: 10),
Text('Loading'),
],
),
),
);
},
);
}
void showSuccessModal(BuildContext context) {
showDialog<void>(
context: context,
barrierDismissible: false,
builder: (BuildContext context) {
return AlertDialog(
title: const Text('Success!'),
actions: <Widget>[
TextButton(
child: const Text('Close'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
}
@override
Widget build(BuildContext context) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () async {
showLoadingModal(context);
await Future.delayed(const Duration(seconds: 5));
Navigator.of(context).pop(); // Close showLoadingModal
showSuccessModal(context);
},
child: const Text("button"))
],
),
);
}
}
この記事が気に入ったらサポートをしてみませんか?