loading_dialog.dart 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. import 'package:flutter/material.dart';
  2. import 'package:tdesign_flutter/tdesign_flutter.dart';
  3. import '../../core/i18n/app_localizations.dart';
  4. import '../../core/theme/app_colors_extension.dart';
  5. /// 通用 loading 弹窗。
  6. ///
  7. /// 深灰色半透明蒙版,居中 loading 动画 + 可自定义文本。
  8. /// 蒙版透明但不可点击穿透。
  9. ///
  10. /// 使用方式:
  11. /// ```dart
  12. /// LoadingDialog.show(context, text: '数据加载中...');
  13. /// // ... 异步操作 ...
  14. /// LoadingDialog.hide(context);
  15. /// ```
  16. class LoadingDialog {
  17. LoadingDialog._();
  18. /// 显示 loading 弹窗。[text] 默认为 i18n "loading"(加载中…)。
  19. static void show(BuildContext context, {String? text}) {
  20. showDialog(
  21. context: context,
  22. barrierColor: Colors.transparent,
  23. barrierDismissible: false,
  24. builder: (_) => _LoadingContent(text: text),
  25. );
  26. }
  27. /// 关闭 loading 弹窗。即使弹窗已被关闭也不会抛异常。
  28. static void hide(BuildContext context) {
  29. Navigator.of(context).maybePop();
  30. }
  31. }
  32. class _LoadingContent extends StatelessWidget {
  33. final String? text;
  34. const _LoadingContent({this.text});
  35. @override
  36. Widget build(BuildContext context) {
  37. final l10n = AppLocalizations.of(context);
  38. final colors = Theme.of(context).extension<AppColorsExtension>()!;
  39. return Center(
  40. child: Container(
  41. width: 160,
  42. padding: const EdgeInsets.fromLTRB(16, 24, 16, 20),
  43. decoration: BoxDecoration(
  44. color: colors.loadingCard,
  45. borderRadius: BorderRadius.circular(12),
  46. ),
  47. child: Column(
  48. mainAxisSize: MainAxisSize.min,
  49. children: [
  50. IconTheme(
  51. data: const IconThemeData(color: Colors.white),
  52. child: const TDLoading(
  53. size: TDLoadingSize.large,
  54. icon: TDLoadingIcon.activity,
  55. ),
  56. ),
  57. const SizedBox(height: 14),
  58. Text(
  59. text ?? l10n.get('loading'),
  60. softWrap: false,
  61. style: const TextStyle(
  62. fontSize: 14,
  63. fontWeight: FontWeight.w500,
  64. color: Colors.white,
  65. ),
  66. ),
  67. ],
  68. ),
  69. ),
  70. );
  71. }
  72. }