import 'package:cs_resources/generated/assets.dart'; import 'package:flutter/material.dart'; import 'package:auto_route/auto_route.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:plugin_basic/provider/user_config/user_config_service.dart'; import 'package:router/ext/auto_router_extensions.dart'; import 'package:shared/utils/color_utils.dart'; import 'package:shared/utils/log_utils.dart'; import 'package:widgets/custom_sliver_persistent_header_delegate.dart'; import 'package:widgets/my_load_image.dart'; import 'package:widgets/ext/ex_widget.dart'; import 'package:widgets/my_text_view.dart'; import 'package:widgets/my_appbar.dart'; import 'package:cs_resources/theme/app_colors_theme.dart'; import 'package:widgets/widget_export.dart'; import '../../../router/page/services_page_router.dart'; import 'repair_vm.dart'; final tabsRouterKey = GlobalKey(); final GlobalKey extendedNestedScrollViewKey = GlobalKey(); @RoutePage() class RepairPage extends HookConsumerWidget with WidgetsBindingObserver { RepairPage({Key? key}) : super(key: key); //启动当前页面 static void startInstance({BuildContext? context}) { if (context != null) { context.router.push( RepairPageRoute()); } else { appRouter.push( RepairPageRoute()); } } bool _isKeyboardVisible = false; void handlerNestedScrollViewScroll({double? outerOffset, double? innerOffset, bool? isOuterScrollAnimated=false, bool? isInnerScrollAnimated=false}){ if(outerOffset !=null){ if(isOuterScrollAnimated!){ extendedNestedScrollViewKey.currentState?.outerController.animateTo( outerOffset, duration: const Duration(seconds: 1), curve: Curves.easeIn, ); }else { extendedNestedScrollViewKey.currentState?.outerController.jumpTo( outerOffset, ); } } if(innerOffset !=null){ extendedNestedScrollViewKey.currentState?.innerPositions.forEach((position) { if(isInnerScrollAnimated!){ position.animateTo(innerOffset, duration: Duration(seconds: 1), curve: Curves.easeIn); }else { position.jumpTo(innerOffset); } }); } } @override void didChangeMetrics() { final bottomInset = WidgetsBinding.instance.window.viewInsets.bottom; final newValue = bottomInset > 0.0; if (_isKeyboardVisible != newValue) { _isKeyboardVisible = newValue; if (_isKeyboardVisible) { handlerNestedScrollViewScroll(innerOffset: 0.0,); print("键盘已显示"); } else { WidgetsBinding.instance.removeObserver(this); print("键盘已隐藏"); } } } @override Widget build(BuildContext context, WidgetRef ref) { final vm = ref.read(repairVmProvider.notifier); final state = ref.watch(repairVmProvider); final currentPageIdx = tabsRouterKey.currentState?.controller?.activeIndex ?? 0; useEffect(() { // 监听窗口 WidgetsBinding.instance.addObserver(this); }, []); useEffect((){ Log.d("RepairPage initState"); // 延迟监听 WidgetsBinding.instance?.addPostFrameCallback((timeStamp) { if(tabsRouterKey.currentState?.controller != null){ tabsRouterKey.currentState?.controller?.addListener((){ vm.tabsRouterChange(); }); } }); return (){ Log.d("RepairPage dispose"); WidgetsBinding.instance.removeObserver(this); tabsRouterKey.currentState?.controller?.removeListener(vm.tabsRouterChange); }; },[]); return Scaffold( appBar: MyAppBar.searchAppBar( context, value: vm.getCurrentQueryParams('keyword'), actions: [ const MyAssetImage( Assets.serviceServiceScoreYes, width: 21.5, height: 21.5, ).onTap((){ vm.handlerClickNavbarLikeBtn(context); }), const SizedBox(width: 15), ], backgroundColor: context.appColors.backgroundWhite, onSearch: (value) { vm.handlerSearch(value); } ), backgroundColor: context.appColors.backgroundDefault, body: ExtendedNestedScrollView( key: extendedNestedScrollViewKey, onlyOneScrollInBody: true, headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) { return [ SliverPersistentHeader( delegate: CustomSliverPersistentHeaderDelegate( maxHeight: 130, minHeight: 130, child: _buildTopSection(context, ref, vm, state), ), pinned: currentPageIdx !=0? true:false, ), // top 组件,转换为 Sliver 组件 // SliverToBoxAdapter( // child: _buildTopSection(context, ref, vm, state), // ), ]; }, body: Column( mainAxisSize: MainAxisSize.max, children: [ Expanded( child: AutoTabsRouter.pageView( key: tabsRouterKey, routes: const [ RepairHomeServicePageRoute(), RepairInProgressPageRoute(), RepairHistoryPageRoute(), ], builder: (context, child, pageController) { final tabsRouter = AutoTabsRouter.of(context); return Column( children: [ Expanded(child: child), ], ); }, ) ) ] ) ) ); } Widget _buildTopSection(BuildContext context, WidgetRef ref, vm, state) { final topSectionsData = vm.topSectionsData; final currentPageIdx = tabsRouterKey.currentState?.controller?.activeIndex ?? 0; return Container( color: context.appColors.whiteBG, child: Center( child: Row( mainAxisSize: MainAxisSize.max, mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: List.generate(topSectionsData.length, (index) { final item = topSectionsData[index]; return Column( children: [ Container( width: MediaQuery.of(context).size.width / topSectionsData.length - 36, height: 70, decoration: BoxDecoration( shape: BoxShape.circle, // 设置为圆形 color: ColorUtils.string2Color("#F0F8FF"), boxShadow: index == currentPageIdx ? [ BoxShadow( color: context.appColors.tabLightBlueShadow, // 设置阴影颜色 blurRadius: 5, // 设置模糊半径 spreadRadius: 0.05, // 控制阴影扩散 offset: const Offset(0, 4), // 设置阴影偏移量 ),] : [],// 未选中时无阴影, ), child: MyAssetImage( item['icon'], width: MediaQuery.of(context).size.width / topSectionsData.length - 36, // width: 70, height: 70, ).onTap(() { vm.handlerSwitchPageView(context, index); }, type: ClickType.throttle, ), ), SizedBox.fromSize(size: const Size(0, 9)), MyTextView( item['title'], fontSize: 15, textColor: index == currentPageIdx ? ColorUtils.string2Color('#4161D0'): context.appColors.textBlack, textAlign: TextAlign.center, isFontMedium: true, ), ], ).marginOnly(left: 18, right: 18, top: 10, bottom: 10); }), ), ), ); } }