通信処理は、アプリにとって欠かせない機能のひとつです。ユーザーに対して「いま通信中ですよ」と伝えるためには、インジケータ(ローディング表示)を表示することが大切です。
今回は、Flutter で通信中にインジケータを表示する方法を紹介します!
通信中インジケータの表示方法
以下が Flutter で通信中インジケータを表示するコード例です。showDialog を使って CircularProgressIndicator を表示しています。
CircularProgressIndicator については、以下の記事で詳しく紹介しているのでご参照ください。
import 'package:flutter/material.dart';
class LoadingIndicatorSamplePage extends StatelessWidget {
const LoadingIndicatorSamplePage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("通信中インジケータの表示例"),
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
),
body: Center(
child: ElevatedButton(
onPressed: () {
showIndicator(context, fetchData());
},
child: const Text("データを取得"),
),
),
);
}
Future<String> fetchData() async {
await Future.delayed(const Duration(seconds: 2)); // 通信の代わりに2秒待つ
return 'データ取得完了';
}
void showIndicator(BuildContext context, Future operation) {
showDialog(
context: context,
barrierDismissible: false,
builder: (context) {
return const Center(
child: SizedBox(
width: 100,
height: 100,
child: CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation(Colors.lightBlue),
strokeWidth: 8,
),
),
);
},
);
operation.whenComplete(() {
if (!context.mounted) return;
Navigator.of(context).pop();
});
}
}
上記コードの動作例が以下です。

解説
showDialog で表示するダイアログ上で CircularProgressIndicator を表示しています。
また、barrierDismissible: false にすることで、背景をタップしてもダイアログが閉じないようにしています。
SizedBox で インジケータのサイズを変更できます。
showDialog(
context: context,
barrierDismissible: false,
builder: (context) {
return const Center(
child: SizedBox(
width: 100,
height: 100,
child: CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation(Colors.lightBlue),
strokeWidth: 8,
),
),
);
},
);
showDialog の後の以下の部分で通信(operation)が完了したときに、ダイアログを閉じるようにしています。
if (!context.mounted) return; では、非同期処理の間に、もしウィジェットが破棄(dispose)されていたら、その後の処理をしないようにしています。
operation.whenComplete(() {
if (!context.mounted) return;
Navigator.of(context).pop();
});
まとめ
今回は、Flutter で通信中インジケータを表示する方法について紹介しました!
以上で、【Flutter】通信中のインジケータを表示する方法 は終わりです。