import 'dart:async'; import 'package:cs_resources/generated/assets.dart'; import 'package:cs_resources/generated/l10n.dart'; import 'package:cs_resources/theme/app_colors_theme.dart'; import 'package:flutter/material.dart'; import 'package:auto_route/auto_route.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:router/ext/auto_router_extensions.dart'; import 'package:shared/utils/log_utils.dart'; import 'package:widgets/ext/ex_widget.dart'; import 'package:widgets/my_appbar.dart'; import 'package:widgets/my_button.dart'; import 'package:widgets/my_load_image.dart'; import 'package:widgets/my_text_view.dart'; import 'package:plugin_basic/basic_export.dart'; import '../../router/page/auth_page_router.dart'; import 'attach_input_widget.dart'; import 'select_estate_view_model.dart'; @RoutePage() class SelectEstatePage extends HookConsumerWidget with WidgetsBindingObserver { SelectEstateViewModel? viewModel; bool _isKeyboardVisible = false; //软件是否展示 double _previousBottom = 0; // 用于保存上一个 Insets Function()? throttledShowDropDownDialog; // 定义防抖函数 bool isVisible = true; //页面是否可见 SelectEstatePage({Key? key}) : super(key: key); //启动当前页面 static void startInstance({BuildContext? context}) { if (context != null) { context.router.push(SelectEstatePageRoute()); } else { appRouter.push(SelectEstatePageRoute()); } } @override Widget build(BuildContext context, WidgetRef ref) { viewModel = ref.watch(selectEstateViewModelProvider.notifier); final state = ref.watch(selectEstateViewModelProvider); // 初始化防抖函数 throttledShowDropDownDialog ??= throttle(() { viewModel?.showDropDownDialog(needReLocation: true); }) as Function()?; useEffect(() { // 组件挂载时执行 - 执行接口请求 WidgetsBinding.instance.addObserver(this); return () { // 组件卸载时执行 WidgetsBinding.instance.removeObserver(this); }; }, []); return Scaffold( appBar: MyAppBar.appBar(context, S.current.yy_home_accounts), backgroundColor: context.appColors.backgroundDefault, body: Container( padding: const EdgeInsets.symmetric(horizontal: 38), width: double.infinity, child: VisibilityDetector( key: const Key('select-estate-page'), onVisibilityChanged: (VisibilityInfo info) { // 检测页面是否可见 isVisible = info.visibleFraction > 0; Log.d("检测页面是否可见:$isVisible"); }, child: Column( mainAxisSize: MainAxisSize.max, crossAxisAlignment: CrossAxisAlignment.center, children: [ SingleChildScrollView( scrollDirection: Axis.vertical, physics: const BouncingScrollPhysics(), child: Column( crossAxisAlignment: CrossAxisAlignment.center, children: [ //顶部图片 const MyAssetImage( Assets.authChooseEstateBuilding, width: 267, height: 158, ).marginOnly(top: 28, bottom: 38), MyTextView( S.current.estate_or_building_name, fontSize: 23, marginBottom: 20, textAlign: TextAlign.center, isFontMedium: true, textColor: context.appColors.textBlack, ), //输入资产的名称 AttachInputWidget( onChanged: (context, value) { viewModel?.searchEstate(context, value); }, ), MyTextView( S.current.estate_name_desc, fontSize: 15, marginTop: 19, isFontMedium: true, textColor: context.appColors.textBlack, ), ], )).expanded(), MyButton( onPressed: (){ isVisible = false; viewModel?.submitEstate(); }, text: S.current.next, textColor: Colors.white, backgroundColor: context.appColors.btnBgDefault, fontWeight: FontWeight.w500, type: ClickType.throttle, fontSize: 16, minHeight: 50, radius: 5, ).marginOnly(top: 50, bottom: 50), ], ), ), ), ); } @override void didChangeMetrics() { //页面不可见时不走逻辑 if (!isVisible) return; // 当键盘弹出或收起时,这里会被调用 final currentInsets = WidgetsBinding.instance.window.viewInsets; if (currentInsets.bottom > 0 && _previousBottom == 0) { //键盘已弹出 _isKeyboardVisible = true; } else if (currentInsets.bottom == 0 && _previousBottom > 0) { //键盘已收起 _isKeyboardVisible = false; //软键盘收起的时候,重新布局Attach下拉选弹窗 throttledShowDropDownDialog?.call(); } // 更新上一个 Insets _previousBottom = currentInsets.bottom; } //防抖 throttle 函数 Function throttle(void Function() callback, [int milliseconds = 500]) { bool _isAllowed = true; Timer? _throttleTimer; return () { if (!_isAllowed) return; _isAllowed = false; callback(); _throttleTimer?.cancel(); _throttleTimer = Timer(Duration(milliseconds: milliseconds), () { _isAllowed = true; }); }; } }