Profile_edit_page.dart 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. import 'package:cpt_profile/modules/profile_edit/profile_edit_state.dart';
  2. import 'package:cpt_profile/modules/profile_edit/profile_edit_view_model.dart';
  3. import 'package:cpt_profile/router/page/profile_page_router.dart';
  4. import 'package:cs_resources/generated/assets.dart';
  5. import 'package:cs_resources/generated/l10n.dart';
  6. import 'package:cs_resources/theme/app_colors_theme.dart';
  7. import 'package:flutter/material.dart';
  8. import 'package:auto_route/auto_route.dart';
  9. import 'package:flutter_hooks/flutter_hooks.dart';
  10. import 'package:hooks_riverpod/hooks_riverpod.dart';
  11. import 'package:router/ext/auto_router_extensions.dart';
  12. import 'package:widgets/ext/ex_widget.dart';
  13. import 'package:widgets/my_appbar.dart';
  14. import 'package:widgets/my_button.dart';
  15. import 'package:widgets/my_load_image.dart';
  16. import 'package:widgets/my_text_field.dart';
  17. import 'package:widgets/my_text_view.dart';
  18. import 'package:widgets/widget_export.dart';
  19. @RoutePage()
  20. class ProfileEditPage extends HookConsumerWidget {
  21. const ProfileEditPage({Key? key}) : super(key: key);
  22. //启动当前页面
  23. static void startInstance({BuildContext? context}) {
  24. if (context != null) {
  25. context.router.push(const ProfileEditPageRoute());
  26. } else {
  27. appRouter.push(const ProfileEditPageRoute());
  28. }
  29. }
  30. @override
  31. Widget build(BuildContext context, WidgetRef ref) {
  32. final viewModel = ref.watch(profileEditViewModelProvider.notifier);
  33. final state = ref.watch(profileEditViewModelProvider);
  34. useEffect(() {
  35. // 执行接口请求
  36. Future.microtask(() => viewModel.fetchDefaultAvatar());
  37. return () {
  38. };
  39. }, []);
  40. return Scaffold(
  41. appBar: MyAppBar.appBar(context, S.current.edit_profile,backgroundColor: context.appColors.backgroundWhite),
  42. backgroundColor: context.appColors.backgroundDefault,
  43. body: SingleChildScrollView(
  44. scrollDirection: Axis.vertical,
  45. physics: const BouncingScrollPhysics(),
  46. child: Container(
  47. margin: const EdgeInsets.symmetric(horizontal: 15),
  48. width: double.infinity,
  49. child: Column(
  50. mainAxisSize: MainAxisSize.max,
  51. crossAxisAlignment: CrossAxisAlignment.start,
  52. children: [
  53. Center(
  54. child: Container(
  55. width: 80,
  56. height: 80,
  57. decoration: BoxDecoration(color: context.appColors.avatarBg, shape: BoxShape.circle),
  58. child: Stack(
  59. children: [
  60. //默认的占位图
  61. Visibility(
  62. visible: state.avatarPath == null,
  63. child: const Align(
  64. alignment: Alignment.bottomCenter,
  65. child: MyAssetImage(
  66. Assets.profileEditProfileAvatarDefault,
  67. width: 49,
  68. height: 64,
  69. ),
  70. ),
  71. ),
  72. //用户的头像
  73. Visibility(
  74. visible: state.avatarPath != null,
  75. child: MyLoadImage(
  76. state.avatarPath,
  77. width: 80,
  78. height: 80,
  79. isCircle: true,
  80. ),
  81. ),
  82. //底部的背景色
  83. const Align(
  84. alignment: Alignment.bottomCenter,
  85. child: MyAssetImage(
  86. Assets.profileEditProfileAvatarBottom,
  87. width: 71,
  88. height: 21.5,
  89. ),
  90. ),
  91. //照相机Icon
  92. const Align(
  93. alignment: Alignment.bottomCenter,
  94. child: MyAssetImage(
  95. Assets.profileEditProfileAdd,
  96. width: 12,
  97. height: 11.5,
  98. ),
  99. ).marginOnly(bottom: 4),
  100. ],
  101. ),
  102. ).onTap((){
  103. viewModel.showAvatarEditDialog(context);
  104. }),
  105. ).marginOnly(top: 23),
  106. // 表单 - 名
  107. MyTextView(
  108. S.current.first_name,
  109. fontSize: 17,
  110. marginTop: 33,
  111. marginBottom: 16,
  112. isFontMedium: true,
  113. textColor: context.appColors.textBlack,
  114. ),
  115. //表单
  116. _buildInputLayout(
  117. context,
  118. state,
  119. "first_name",
  120. textInputType: TextInputType.text,
  121. textInputAction: TextInputAction.next,
  122. onSubmit: (formKey, value) {
  123. state.formData[formKey]!['focusNode'].unfocus();
  124. FocusScope.of(context).requestFocus(state.formData['last_name']!['focusNode']);
  125. },
  126. ),
  127. // 表单 - 姓
  128. MyTextView(
  129. S.current.last_name,
  130. fontSize: 17,
  131. marginTop: 15,
  132. marginBottom: 16,
  133. isFontMedium: true,
  134. textColor: context.appColors.textBlack,
  135. ),
  136. //表单
  137. _buildInputLayout(
  138. context,
  139. state,
  140. "last_name",
  141. textInputType: TextInputType.text,
  142. textInputAction: TextInputAction.next,
  143. onSubmit: (formKey, value) {
  144. state.formData[formKey]!['focusNode'].unfocus();
  145. FocusScope.of(context).requestFocus(state.formData['email']!['focusNode']);
  146. },
  147. ),
  148. // 表单 - 邮箱
  149. MyTextView(
  150. S.current.email,
  151. fontSize: 17,
  152. marginTop: 15,
  153. marginBottom: 16,
  154. isFontMedium: true,
  155. textColor: context.appColors.textBlack,
  156. ),
  157. //表单
  158. _buildInputLayout(
  159. context,
  160. state,
  161. "email",
  162. textInputType: TextInputType.emailAddress,
  163. textInputAction: TextInputAction.next,
  164. onSubmit: (formKey, value) {
  165. state.formData[formKey]!['focusNode'].unfocus();
  166. },
  167. ),
  168. //提交
  169. MyButton(
  170. onPressed: viewModel.submitEdit,
  171. text: S.current.submit,
  172. textColor: Colors.white,
  173. backgroundColor: context.appColors.btnBgDefault,
  174. fontWeight: FontWeight.w500,
  175. type: ClickType.throttle,
  176. fontSize: 16,
  177. minHeight: 50,
  178. radius: 5,
  179. ).marginOnly(top: 50, bottom: 50),
  180. ],
  181. ),
  182. ),
  183. ),
  184. );
  185. }
  186. /// 输入框
  187. Widget _buildInputLayout(
  188. BuildContext context,
  189. ProfileEditState state,
  190. String key, {
  191. double marginTop = 0,
  192. bool? showRightIcon = false, //是否展示右侧的布局
  193. Widget? rightWidget, //右侧的布局
  194. TextInputType textInputType = TextInputType.text,
  195. String? errorText,
  196. bool obscureText = false,
  197. TextInputAction textInputAction = TextInputAction.done,
  198. Function? onSubmit,
  199. }) {
  200. return IgnoreKeyboardDismiss(
  201. child: MyTextField(
  202. key,
  203. fillBackgroundColor: context.appColors.authFiledBG,
  204. state.formData[key]!['value'],
  205. hintText: state.formData[key]!['hintText'],
  206. hintStyle: TextStyle(
  207. color: context.appColors.authFiledHint,
  208. fontSize: 16.0,
  209. fontWeight: FontWeight.w500,
  210. ),
  211. controller: state.formData[key]!['controller'],
  212. focusNode: state.formData[key]!['focusNode'],
  213. margin: EdgeInsets.only(top: marginTop),
  214. padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 3),
  215. showDivider: false,
  216. height: 44,
  217. style: TextStyle(
  218. color: context.appColors.authFiledText,
  219. fontSize: 16.0,
  220. fontWeight: FontWeight.w500,
  221. ),
  222. inputType: textInputType,
  223. textInputAction: textInputAction,
  224. onSubmit: onSubmit,
  225. cursorColor: context.appColors.authFiledText,
  226. obscureText: obscureText,
  227. errorText: errorText,
  228. showLeftIcon: true,
  229. showRightIcon: showRightIcon,
  230. rightWidget: rightWidget,
  231. ),
  232. );
  233. }
  234. }