|
@@ -1,24 +1,31 @@
|
|
|
-import 'package:cpt_auth/modules/select_estate/select_estate_state.dart';
|
|
|
+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_field.dart';
|
|
|
import 'package:widgets/my_text_view.dart';
|
|
|
-import 'package:widgets/widget_export.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 {
|
|
|
+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);
|
|
|
|
|
|
//启动当前页面
|
|
@@ -32,127 +39,134 @@ class SelectEstatePage extends HookConsumerWidget {
|
|
|
|
|
|
@override
|
|
|
Widget build(BuildContext context, WidgetRef ref) {
|
|
|
- final viewModel = ref.watch(selectEstateViewModelProvider.notifier);
|
|
|
+ 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: 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,
|
|
|
- ),
|
|
|
-
|
|
|
- //输入资产的名称
|
|
|
- _buildInputLayout(
|
|
|
- context,
|
|
|
- state,
|
|
|
- "estate",
|
|
|
- textInputAction: TextInputAction.done,
|
|
|
- onSubmit: (formKey, value) {
|
|
|
- state.formData[formKey]!['focusNode'].unfocus();
|
|
|
- },
|
|
|
- ),
|
|
|
-
|
|
|
- MyTextView(
|
|
|
- S.current.estate_name_desc,
|
|
|
- fontSize: 15,
|
|
|
- marginTop: 19,
|
|
|
- isFontMedium: true,
|
|
|
- textColor: context.appColors.textBlack,
|
|
|
- ),
|
|
|
- ],
|
|
|
- )).expanded(),
|
|
|
-
|
|
|
- MyButton(
|
|
|
- onPressed: 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),
|
|
|
- ],
|
|
|
+ child: VisibilityDetector(
|
|
|
+ key: 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),
|
|
|
+ ],
|
|
|
+ ),
|
|
|
),
|
|
|
),
|
|
|
);
|
|
|
}
|
|
|
|
|
|
- /// 输入框
|
|
|
- Widget _buildInputLayout(
|
|
|
- BuildContext context,
|
|
|
- SelectEstateState state,
|
|
|
- String formKey, {
|
|
|
- Key? key,
|
|
|
- double marginTop = 0,
|
|
|
- bool? showRightIcon = false, //是否展示右侧的布局
|
|
|
- Widget? rightWidget, //右侧的布局
|
|
|
- TextInputType textInputType = TextInputType.text,
|
|
|
- String? errorText,
|
|
|
- bool obscureText = false,
|
|
|
- TextInputAction textInputAction = TextInputAction.done,
|
|
|
- Function? onSubmit,
|
|
|
- }) {
|
|
|
- return IgnoreKeyboardDismiss(
|
|
|
- child: MyTextField(
|
|
|
- formKey,
|
|
|
- key: key,
|
|
|
- fillBackgroundColor: context.appColors.authFiledBG,
|
|
|
- state.formData[formKey]!['value'],
|
|
|
- hintText: state.formData[formKey]!['hintText'],
|
|
|
- hintStyle: TextStyle(
|
|
|
- color: context.appColors.authFiledHint,
|
|
|
- fontSize: 16.0,
|
|
|
- fontWeight: FontWeight.w500,
|
|
|
- ),
|
|
|
- controller: state.formData[formKey]!['controller'],
|
|
|
- focusNode: state.formData[formKey]!['focusNode'],
|
|
|
- margin: EdgeInsets.only(top: marginTop),
|
|
|
- padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 3),
|
|
|
- showDivider: false,
|
|
|
- height: 44,
|
|
|
- style: TextStyle(
|
|
|
- color: context.appColors.authFiledText,
|
|
|
- fontSize: 16.0,
|
|
|
- fontWeight: FontWeight.w500,
|
|
|
- ),
|
|
|
- inputType: textInputType,
|
|
|
- textInputAction: textInputAction,
|
|
|
- onSubmit: onSubmit,
|
|
|
- cursorColor: context.appColors.authFiledText,
|
|
|
- obscureText: obscureText,
|
|
|
- errorText: errorText,
|
|
|
- showLeftIcon: true,
|
|
|
- showRightIcon: showRightIcon,
|
|
|
- rightWidget: rightWidget,
|
|
|
- ),
|
|
|
- );
|
|
|
+ @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;
|
|
|
+ });
|
|
|
+ };
|
|
|
}
|
|
|
}
|