import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:flutter_spinkit/flutter_spinkit.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:get/get.dart'; import 'package:nomo/config/theme/theme_extensions/theme_extension.dart'; import '../../../config/translations/strings_enum.dart'; import '../../base/base_controller.dart'; import '../../constants/assets.dart'; import '../../constants/enums.dart'; import '../submit_btn.dart'; class StateWrapper extends StatelessWidget { final Widget child; final BaseController controller; final double? width; final double? height; final VoidCallback? onRefresh; // 可选的自定义状态视图 final Widget Function(BuildContext)? loadingBuilder; final Widget Function(BuildContext)? emptyBuilder; final Widget Function(BuildContext, String?)? errorBuilder; const StateWrapper({ super.key, required this.child, required this.controller, this.width, this.height, this.loadingBuilder, this.emptyBuilder, this.errorBuilder, this.onRefresh, }); // 默认加载视图 Widget _defaultLoadingView(BuildContext context) { return Center( // child: CircularProgressIndicator(), child: SpinKitRing( size: 24.w, lineWidth: 2.w, color: Get.reactiveTheme.primaryColor, ), ); } // 默认空视图 Widget _defaultEmptyView(BuildContext context) { return Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ SvgPicture.asset(Assets.oops, width: 160.w, height: 160.w), Text( Strings.noData.tr, style: TextStyle( fontSize: 14.sp, color: Get.reactiveTheme.textTheme.bodyLarge!.color!, ), ), 24.verticalSpaceFromWidth, SizedBox( width: 247.w, child: SubmitSvgButton( onPressed: onRefresh ?? () {}, text: Strings.refresh.tr, svgPath: Assets.refersh, svgColor: Get.reactiveTheme.textTheme.bodyLarge!.color, bgColor: Get.reactiveTheme.primaryColor, textColor: Get.reactiveTheme.textTheme.bodyLarge!.color, borderColor: Get.reactiveTheme.dividerColor, ), ), 40.verticalSpaceFromWidth, ], ), ); } // 默认错误视图 Widget _defaultErrorView( BuildContext context, bool isNetworkError, String error, ) { return Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ SvgPicture.asset( isNetworkError ? Assets.oops : Assets.oops, width: 160.w, height: 160.w, ), Padding( padding: EdgeInsets.symmetric(horizontal: 20.w), child: Text( error.isNotEmpty ? error : Strings.unableToConnectServer.tr, style: TextStyle( fontSize: 14.sp, color: Get.reactiveTheme.textTheme.bodyLarge!.color, ), ), ), 24.verticalSpaceFromWidth, SizedBox( width: 247.w, child: SubmitSvgButton( onPressed: onRefresh ?? () {}, text: Strings.retry.tr, svgPath: Assets.refersh, svgColor: Get.reactiveTheme.textTheme.bodyLarge!.color, bgColor: Get.reactiveTheme.primaryColor, textColor: Get.reactiveTheme.textTheme.bodyLarge!.color, borderColor: Get.reactiveTheme.dividerColor, ), ), 40.verticalSpaceFromWidth, ], ), ); } @override Widget build(BuildContext context) { return SizedBox( width: width, height: height, child: Obx(() { switch (controller.viewState.value) { case ViewState.loading: return loadingBuilder?.call(context) ?? _defaultLoadingView(context); case ViewState.empty: return emptyBuilder?.call(context) ?? _defaultEmptyView(context); case ViewState.error: return errorBuilder?.call(context, controller.errorMessage.value) ?? _defaultErrorView( context, controller.isNetworkError.value, controller.errorMessage.value, ); case ViewState.success: return child; } }), ); } }