|
...
|
...
|
@@ -2,6 +2,11 @@ import 'package:flutter/material.dart'; |
|
|
|
import 'package:get/get.dart';
|
|
|
|
import 'package:lottie/lottie.dart';
|
|
|
|
|
|
|
|
/// Loading 动画类型
|
|
|
|
/// - [lottie] 默认,使用 Lottie 动画(现有行为,保持不变)
|
|
|
|
/// - [circular] 使用系统 CircularProgressIndicator
|
|
|
|
enum LoadingType { lottie, circular }
|
|
|
|
|
|
|
|
class LoadingService {
|
|
|
|
OverlayEntry? _entry;
|
|
|
|
int _counter = 0;
|
|
...
|
...
|
@@ -13,8 +18,9 @@ class LoadingService { |
|
|
|
static LoadingService get instance => Get.find();
|
|
|
|
|
|
|
|
/// 包装一个异步操作,执行期间显示 Loading,完成后自动隐藏。
|
|
|
|
Future<T> run<T>(Future<T> Function() block) async {
|
|
|
|
show();
|
|
|
|
Future<T> run<T>(Future<T> Function() block,
|
|
|
|
{LoadingType type = LoadingType.lottie}) async {
|
|
|
|
show(type: type);
|
|
|
|
try {
|
|
|
|
return await block();
|
|
|
|
} finally {
|
|
...
|
...
|
@@ -22,7 +28,7 @@ class LoadingService { |
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void show() {
|
|
|
|
void show({LoadingType type = LoadingType.lottie}) {
|
|
|
|
_counter++;
|
|
|
|
if (_counter > 1) return;
|
|
|
|
|
|
...
|
...
|
@@ -35,7 +41,9 @@ class LoadingService { |
|
|
|
|
|
|
|
// 防御:清理可能残留的旧 entry
|
|
|
|
_entry?.remove();
|
|
|
|
_entry = OverlayEntry(builder: (_) => const _GlobalLoadingWidget());
|
|
|
|
_entry = OverlayEntry(
|
|
|
|
builder: (_) => _GlobalLoadingWidget(type: type),
|
|
|
|
);
|
|
|
|
overlay.insert(_entry!);
|
|
|
|
}
|
|
|
|
|
|
...
|
...
|
@@ -50,7 +58,9 @@ class LoadingService { |
|
|
|
}
|
|
|
|
|
|
|
|
class _GlobalLoadingWidget extends StatelessWidget {
|
|
|
|
const _GlobalLoadingWidget();
|
|
|
|
const _GlobalLoadingWidget({this.type = LoadingType.lottie});
|
|
|
|
|
|
|
|
final LoadingType type;
|
|
|
|
|
|
|
|
@override
|
|
|
|
Widget build(BuildContext context) {
|
|
...
|
...
|
@@ -63,16 +73,27 @@ class _GlobalLoadingWidget extends StatelessWidget { |
|
|
|
color: Colors.black.withValues(alpha: 0.3),
|
|
|
|
child: Align(
|
|
|
|
alignment: const Alignment(0.0, -0.1),
|
|
|
|
child: Lottie.asset(
|
|
|
|
'assets/lottie/loading.json',
|
|
|
|
width: 130,
|
|
|
|
height: 90,
|
|
|
|
repeat: true,
|
|
|
|
animate: true,
|
|
|
|
),
|
|
|
|
child: _buildIndicator(),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
Widget _buildIndicator() {
|
|
|
|
switch (type) {
|
|
|
|
case LoadingType.lottie:
|
|
|
|
return Lottie.asset(
|
|
|
|
'assets/lottie/loading.json',
|
|
|
|
width: 130,
|
|
|
|
height: 90,
|
|
|
|
repeat: true,
|
|
|
|
animate: true,
|
|
|
|
);
|
|
|
|
case LoadingType.circular:
|
|
|
|
return const CircularProgressIndicator(
|
|
|
|
strokeWidth: 3,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} |
...
|
...
|
|