select_unit_page.dart 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296
  1. import 'package:cpt_auth/modules/select_estate/select_estate_state.dart';
  2. import 'package:cs_resources/generated/assets.dart';
  3. import 'package:cs_resources/generated/l10n.dart';
  4. import 'package:cs_resources/theme/app_colors_theme.dart';
  5. import 'package:flutter/material.dart';
  6. import 'package:auto_route/auto_route.dart';
  7. import 'package:flutter_hooks/flutter_hooks.dart';
  8. import 'package:hooks_riverpod/hooks_riverpod.dart';
  9. import 'package:router/ext/auto_router_extensions.dart';
  10. import 'package:shared/utils/log_utils.dart';
  11. import 'package:widgets/ext/ex_widget.dart';
  12. import 'package:widgets/my_appbar.dart';
  13. import 'package:widgets/my_button.dart';
  14. import 'package:widgets/my_load_image.dart';
  15. import 'package:widgets/my_text_field.dart';
  16. import 'package:widgets/my_text_view.dart';
  17. import 'package:widgets/widget_export.dart';
  18. import '../../router/page/auth_page_router.dart';
  19. import 'select_unit_state.dart';
  20. import 'select_unit_view_model.dart';
  21. @RoutePage()
  22. class SelectUnitPage extends HookConsumerWidget {
  23. SelectUnitPage({Key? key}) : super(key: key);
  24. //启动当前页面
  25. static void startInstance({BuildContext? context}) {
  26. if (context != null) {
  27. context.router.push(SelectUnitPageRoute());
  28. } else {
  29. appRouter.push(SelectUnitPageRoute());
  30. }
  31. }
  32. // 为需要测量的控件创建 GlobalKey
  33. final GlobalKey _appbarKey = GlobalKey();
  34. final GlobalKey _topImageKey = GlobalKey();
  35. final GlobalKey _inputKey = GlobalKey();
  36. final GlobalKey _description1Key = GlobalKey();
  37. final GlobalKey _description2Key = GlobalKey();
  38. final GlobalKey _description3Key = GlobalKey();
  39. final GlobalKey _buttonKey = GlobalKey();
  40. @override
  41. Widget build(BuildContext context, WidgetRef ref) {
  42. final viewModel = ref.watch(selectUnitViewModelProvider.notifier);
  43. final state = ref.watch(selectUnitViewModelProvider);
  44. // 获取屏幕高度
  45. final screenHeight = MediaQuery.of(context).size.height;
  46. final statusBarHeight = MediaQuery.of(context).padding.top;
  47. final navigationBarHeight = MediaQuery.of(context).padding.bottom;
  48. useEffect(() {
  49. double usedHeight = 0;
  50. // 组件挂载时执行,获取控件高度
  51. WidgetsBinding.instance.addPostFrameCallback((_) {
  52. // 获取各个控件的高度
  53. usedHeight += _appbarKey.currentContext?.size?.height ?? 0;
  54. usedHeight += _topImageKey.currentContext?.size?.height ?? 0;
  55. usedHeight += _inputKey.currentContext?.size?.height ?? 0;
  56. usedHeight += _description1Key.currentContext?.size?.height ?? 0;
  57. usedHeight += _description2Key.currentContext?.size?.height ?? 0;
  58. usedHeight += _description3Key.currentContext?.size?.height ?? 0;
  59. usedHeight += _buttonKey.currentContext?.size?.height ?? 0;
  60. // 计算剩余空间
  61. double remainingSpace = screenHeight - statusBarHeight - navigationBarHeight - usedHeight - 28 - 18 - 25 - 20 - 20;
  62. Log.d("计算剩余空间:$remainingSpace");
  63. if (remainingSpace > 0) {
  64. // 设置一个状态来存储剩余空间的高度
  65. viewModel.setRemainingSpace(remainingSpace);
  66. }
  67. });
  68. return () {
  69. // 组件卸载时执行
  70. };
  71. }, []);
  72. return Scaffold(
  73. appBar: MyAppBar.appBar(context, S.current.yy_home_accounts, key: _appbarKey),
  74. backgroundColor: context.appColors.backgroundDefault,
  75. body: SingleChildScrollView(
  76. scrollDirection: Axis.vertical,
  77. physics: const BouncingScrollPhysics(),
  78. child: Container(
  79. padding: const EdgeInsets.symmetric(horizontal: 20),
  80. width: double.infinity,
  81. child: Column(
  82. mainAxisSize: MainAxisSize.max,
  83. crossAxisAlignment: CrossAxisAlignment.center,
  84. children: [
  85. //顶部图片
  86. MyAssetImage(
  87. key: _topImageKey,
  88. Assets.authSignUpUnitImg,
  89. width: 266.5,
  90. height: 162,
  91. ).marginOnly(top: 28, bottom: 18),
  92. Row(
  93. key: _inputKey,
  94. mainAxisSize: MainAxisSize.min,
  95. children: [
  96. //街区
  97. Column(
  98. crossAxisAlignment: CrossAxisAlignment.start,
  99. children: [
  100. MyTextView(
  101. S.current.block,
  102. marginBottom: 9,
  103. textColor: context.appColors.textBlack,
  104. fontSize: 16,
  105. isFontMedium: true,
  106. ),
  107. // 表单 - 街区
  108. _buildInputLayout(
  109. context,
  110. state,
  111. "block",
  112. textInputAction: TextInputAction.next,
  113. onSubmit: (formKey, value) {
  114. state.formData[formKey]!['focusNode'].unfocus();
  115. FocusScope.of(context).requestFocus(state.formData['unit']!['focusNode']);
  116. },
  117. ).constrained(width: 88),
  118. ],
  119. ),
  120. MyTextView(
  121. "#",
  122. marginTop: 20,
  123. marginLeft: 8.5,
  124. marginRight: 8.5,
  125. textColor: context.appColors.textBlack,
  126. fontSize: 16,
  127. isFontMedium: true,
  128. ),
  129. //单元
  130. Column(
  131. crossAxisAlignment: CrossAxisAlignment.start,
  132. children: [
  133. MyTextView(
  134. S.current.unit_number,
  135. marginBottom: 9,
  136. textColor: context.appColors.textBlack,
  137. fontSize: 16,
  138. isFontMedium: true,
  139. ),
  140. Row(
  141. children: [
  142. // 表单 - 单元
  143. _buildInputLayout(
  144. context,
  145. state,
  146. "unit",
  147. textInputAction: TextInputAction.next,
  148. onSubmit: (formKey, value) {
  149. state.formData[formKey]!['focusNode'].unfocus();
  150. FocusScope.of(context).requestFocus(state.formData['room']!['focusNode']);
  151. },
  152. ).constrained(width: 83),
  153. MyTextView(
  154. "-",
  155. textColor: context.appColors.textBlack,
  156. marginLeft: 4,
  157. marginRight: 4,
  158. isFontMedium: true,
  159. ),
  160. // 表单 - 房号
  161. _buildInputLayout(
  162. context,
  163. state,
  164. "room",
  165. textInputAction: TextInputAction.done,
  166. onSubmit: (formKey, value) {
  167. state.formData[formKey]!['focusNode'].unfocus();
  168. },
  169. ).constrained(width: 83),
  170. ],
  171. ),
  172. ],
  173. ),
  174. ],
  175. ),
  176. MyTextView(
  177. key: _description1Key,
  178. S.current.block_desc,
  179. fontSize: 15,
  180. marginTop: 25,
  181. textAlign: TextAlign.center,
  182. isFontMedium: true,
  183. textColor: context.appColors.textBlack,
  184. ),
  185. MyTextView(
  186. key: _description2Key,
  187. S.current.block_example,
  188. fontSize: 15,
  189. marginTop: 20,
  190. textAlign: TextAlign.center,
  191. isFontMedium: true,
  192. textColor: context.appColors.textBlack,
  193. ),
  194. MyTextView(
  195. key: _description3Key,
  196. S.current.block_example_desc,
  197. fontSize: 15,
  198. marginTop: 20,
  199. textAlign: TextAlign.center,
  200. isFontMedium: true,
  201. textColor: context.appColors.textBlack,
  202. ),
  203. SizedBox(
  204. height: state.remainingSpace, // 使用剩余空间的值
  205. ),
  206. MyButton(
  207. key: _buttonKey,
  208. onPressed: viewModel.submitUnit,
  209. text: S.current.next,
  210. textColor: Colors.white,
  211. backgroundColor: context.appColors.btnBgDefault,
  212. fontWeight: FontWeight.w500,
  213. type: ClickType.throttle,
  214. fontSize: 16,
  215. minHeight: 50,
  216. radius: 5,
  217. ).marginOnly(top: 40, bottom: 30, left: 18, right: 18),
  218. ],
  219. ),
  220. ),
  221. ),
  222. );
  223. }
  224. /// 输入框
  225. Widget _buildInputLayout(
  226. BuildContext context,
  227. SelectUnitState state,
  228. String key, {
  229. double marginTop = 0,
  230. bool? showRightIcon = false, //是否展示右侧的布局
  231. Widget? rightWidget, //右侧的布局
  232. TextInputType textInputType = TextInputType.number,
  233. String? errorText,
  234. bool obscureText = false,
  235. TextInputAction textInputAction = TextInputAction.done,
  236. Function? onSubmit,
  237. }) {
  238. return IgnoreKeyboardDismiss(
  239. child: MyTextField(
  240. key,
  241. fillBackgroundColor: context.appColors.authFiledBG,
  242. state.formData[key]!['value'],
  243. hintText: state.formData[key]!['hintText'],
  244. hintStyle: TextStyle(
  245. color: context.appColors.authFiledHint,
  246. fontSize: 16.0,
  247. fontWeight: FontWeight.w500,
  248. ),
  249. controller: state.formData[key]!['controller'],
  250. focusNode: state.formData[key]!['focusNode'],
  251. margin: EdgeInsets.only(top: marginTop),
  252. padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 3),
  253. showDivider: false,
  254. height: 44,
  255. style: TextStyle(
  256. color: context.appColors.authFiledText,
  257. fontSize: 16.0,
  258. fontWeight: FontWeight.w500,
  259. ),
  260. inputType: textInputType,
  261. textInputAction: textInputAction,
  262. onSubmit: onSubmit,
  263. cursorColor: context.appColors.authFiledText,
  264. obscureText: obscureText,
  265. errorText: errorText,
  266. showLeftIcon: true,
  267. showRightIcon: showRightIcon,
  268. rightWidget: rightWidget,
  269. ),
  270. );
  271. }
  272. }