對於回應時間較長的 API,可使用 CircularProgressIndicator
顯示 API Loading 動畫。
Version
Flutter 3.24.5
Flutter
- Android 與 iOS 都成功使用
CircularProgressIndicator
實現 API Loading 動畫
CircularProgressIndicator
import 'package:flutter/material.dart';
class Home extends StatefulWidget {
const Home({super.key});
State<Home> createState() => _Home();
}
class _Home extends State<Home> {
bool _isLoading = false;
Future<void> fetchAPI() async {
try {
await Future.delayed(
Duration(seconds: 3),
);
} catch (e) {
debugPrint('Error: $e');
}
}
Widget build(BuildContext context) {
var appBar = AppBar(
title: Text('API Loading'),
);
var loading = Visibility(
visible: _isLoading,
child: Container(
color: Colors.transparent,
child: Center(
child: CircularProgressIndicator(),
),
),
);
var elevatedButton = Center(
child: ElevatedButton(
onPressed: () async {
setState(() => _isLoading = true);
await fetchAPI();
setState(() => _isLoading = false);
},
child: Text(
'Fetch API',
),
),
);
var body = Stack(
children: [
elevatedButton,
loading,
],
);
return Scaffold(
appBar: appBar,
body: body,
);
}
}
Line 11
bool _isLoading = false;
_isLoading
:定義是否正在 API loading 的 state
Line 13
Future<void> fetchAPI() async {
try {
await Future.delayed(
Duration(seconds: 3),
);
} catch (e) {
debugPrint('Error: $e');
}
}
- 模擬呼叫 API 需要花 3 秒鐘
Line 52
var body = Stack(
children: [
elevatedButton,
loading,
],
);
Stack
:將一般 widget 與loading
一起放在Stack
內
Line 39
var elevatedButton = Center(
child: ElevatedButton(
onPressed: () async {
setState(() => _isLoading = true);
await fetchAPI();
setState(() => _isLoading = false);
},
child: Text(
'Fetch API',
),
),
);
elevatedButton
:一般 button,負責呼叫 API- 在呼叫 API 前將
isLoading
設定為true
,開始顯示 API loading 動畫 - 在 API 回應後將
isLoading
設定為false
,結束顯示 API loading 動畫
Line 29
var loading = Visibility(
visible: _isLoading,
child: Container(
color: Colors.transparent,
child: Center(
child: CircularProgressIndicator(),
),
),
);
CircularProgressIndicator
:API loading 時顯示轉圈圈動畫Visibility
:由_isLoading
state 控制是否顯示
Conclusion
- 由於
loading
與elevatedButton
置於同一個Stack
內,因此當顯示loading
時,elevatedButton
無法被按,還順便做了防呆避免重複呼叫 API