😎
Flutterでお手軽なローディングUIの実装
Flutterでお手軽なローディングUIの実装
非同期処理中にawaitで待っている間、全画面を覆うくるくるUIを実装
SwiftのSVProgressHUDのように手軽に、ローディングUIを使いたい
実装後の利用例
LoadingDialog.show(context); // 表示
await Future.delayed(Duration(seconds: 5)); // API通信処理など
LoadingDialog.hide(context); // 非表示
実装
- LoadingDialogクラスを作成
// 「ローディング」表示のView(ダイアログ)
// 使い方)
// // ローディング表示
// LoadingDialog.show(context);
// // 非同期処理を実行
// await Future.delayed(Duration(seconds: 5));
// // ローディングを非表示
// LoadingDialog.hide(context);
class LoadingDialog extends StatefulWidget {
_LoadingDialogState createState() => _LoadingDialogState();
static void show(BuildContext context) {
showDialog(
context: context,
barrierDismissible: false,
builder: (BuildContext context) {
// NOTE: ↓Flutter v3.16.0~ Deprecated
// 「Android実機の戻るボタン」を無効にする(NOTE: Flutter v3.16.0以前の実装方法)
// return WillPopScope(
// onWillPop: () async => false,
// child: LoadingDialog()
// );
// 「Android実機の戻るボタン」を無効にする(NOTE: Flutter v3.16.0~)
return PopScope(
canPop: false,
child: LoadingDialog(),
);
}
);
}
static void hide(BuildContext context) {
Navigator.of(context).pop();
}
}
class _LoadingDialogState extends State<LoadingDialog> {
Widget build(BuildContext context) {
return Center(
child: SizedBox(
width: 150,
height: 150,
child: AlertDialog(
// backgroundColor: Colors.green, // MEMO: 背景色の指定
alignment: Alignment.center,
contentPadding: EdgeInsets.zero,
insetPadding: EdgeInsets.zero,
content: _dialogContent(),
),
),
);
}
// ダイアログ内に表示するWidget
Widget _dialogContent() {
return Container(
child: Column(
children: [
Spacer(),
CircularProgressIndicator(),
Spacer(),
Text('Loading...'),
// Text('Loading...', style: TextStyle(fontSize: 18,fontWeight: FontWeight.w100),),
Spacer(),
],
),
);
}
}
ポイント
- Adnroid実機の戻るボタン(スワイプで戻る)を、無効化する実装
- Dialogのcontent設定時に、DefaultのPadding値を無効化する実装
その他
-
引数でcontext必須のため、基本的にUI層で使うことを想定。
(Widget以外で使いたい場合、contextをバケツリレーで渡すか、GlobalKey使っていつでもcontextにアクセス可能な仕組みを用意?) -
ダイアログは、設定済のpadding等があるのでそれらを無効にする設定をしないと、widthの小さい値などが、正確に表示されない(contentPadding、insetPaddingの EdgeInsets.zero)
Discussion