add_card_page.dart 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. import 'package:cpt_payment/modules/choose_card/choose_card_page.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:hooks_riverpod/hooks_riverpod.dart';
  8. import 'package:router/ext/auto_router_extensions.dart';
  9. import 'package:widgets/ext/ex_widget.dart';
  10. import 'package:widgets/my_appbar.dart';
  11. import 'package:widgets/my_button.dart';
  12. import 'package:widgets/my_load_image.dart';
  13. import 'package:widgets/my_text_view.dart';
  14. import 'package:widgets/my_text_field.dart';
  15. import 'package:widgets/utils/dark_theme_util.dart';
  16. import 'package:widgets/widget_export.dart';
  17. import '../../router/page/payment_page_router.dart';
  18. import 'add_card_state.dart';
  19. import 'add_card_view_model.dart';
  20. @RoutePage()
  21. class AddCardPage extends HookConsumerWidget {
  22. const AddCardPage({Key? key}) : super(key: key);
  23. //启动当前页面
  24. static void startInstance({BuildContext? context}) {
  25. if (context != null) {
  26. context.router.push(const AddCardPageRoute());
  27. } else {
  28. appRouter.push(const AddCardPageRoute());
  29. }
  30. }
  31. @override
  32. Widget build(BuildContext context, WidgetRef ref) {
  33. final viewModel = ref.read(addCardViewModelProvider.notifier);
  34. final state = ref.watch(addCardViewModelProvider);
  35. return Scaffold(
  36. appBar: MyAppBar.appBar(context, S.current.add_new_card),
  37. backgroundColor: context.appColors.backgroundWhite,
  38. body: SizedBox(
  39. width: double.infinity,
  40. child: Column(
  41. mainAxisSize: MainAxisSize.max,
  42. crossAxisAlignment: CrossAxisAlignment.start,
  43. children: [
  44. SingleChildScrollView(
  45. scrollDirection: Axis.vertical,
  46. physics: const BouncingScrollPhysics(),
  47. child: Column(
  48. crossAxisAlignment: CrossAxisAlignment.start,
  49. children: [
  50. const Row(
  51. mainAxisAlignment: MainAxisAlignment.spaceAround,
  52. children: [
  53. MyAssetImage(Assets.paymentMasterCardIcon, width: 51, height: 30.5),
  54. MyAssetImage(Assets.paymentVisaIcon, width: 78.5, height: 25.5),
  55. MyAssetImage(Assets.paymentAmericanExpressIcon, width: 47, height: 29),
  56. ],
  57. ).marginOnly(left: 20, right: 20, top: 32, bottom: 32),
  58. //信用卡
  59. MyTextView(
  60. S.current.credit_debit_card,
  61. fontSize: 17,
  62. marginLeft: 15,
  63. marginRight: 15,
  64. textColor: context.appColors.textBlack,
  65. isFontMedium: true,
  66. ),
  67. //持卡人姓名
  68. _buildInputLayout(
  69. context,
  70. state,
  71. "card_name",
  72. margin: const EdgeInsets.only(left: 15, right: 15, top: 16),
  73. leftIcon: Assets.paymentCardName,
  74. textInputType: TextInputType.text,
  75. textInputAction: TextInputAction.next,
  76. onSubmit: (formKey, value) {
  77. state.formData[formKey]!['focusNode'].unfocus();
  78. FocusScope.of(context).requestFocus(state.formData['card_number']!['focusNode']);
  79. },
  80. ),
  81. //卡号
  82. _buildInputLayout(
  83. context,
  84. state,
  85. "card_number",
  86. margin: const EdgeInsets.only(left: 15, right: 15, top: 10, bottom: 21),
  87. leftIcon: Assets.paymentCardNumber,
  88. textInputType: TextInputType.number,
  89. textInputAction: TextInputAction.next,
  90. onSubmit: (formKey, value) {
  91. state.formData[formKey]!['focusNode'].unfocus();
  92. FocusScope.of(context).requestFocus(state.formData['month']!['focusNode']);
  93. },
  94. ),
  95. //月份,年份,验证码
  96. Row(
  97. children: [
  98. //月份
  99. _buildInputLayout(
  100. context,
  101. state,
  102. "month",
  103. margin: const EdgeInsets.only(left: 15),
  104. showLeftIcon: false,
  105. textInputType: TextInputType.number,
  106. textInputAction: TextInputAction.next,
  107. onSubmit: (formKey, value) {
  108. state.formData[formKey]!['focusNode'].unfocus();
  109. FocusScope.of(context).requestFocus(state.formData['year']!['focusNode']);
  110. },
  111. ).expanded(),
  112. //年份
  113. _buildInputLayout(
  114. context,
  115. state,
  116. "year",
  117. margin: const EdgeInsets.only(left: 8.5, right: 8.5),
  118. showLeftIcon: false,
  119. textInputType: TextInputType.number,
  120. textInputAction: TextInputAction.next,
  121. onSubmit: (formKey, value) {
  122. state.formData[formKey]!['focusNode'].unfocus();
  123. FocusScope.of(context).requestFocus(state.formData['cyc']!['focusNode']);
  124. },
  125. ).expanded(),
  126. //验证码
  127. _buildInputLayout(
  128. context,
  129. state,
  130. "cyc",
  131. margin: const EdgeInsets.only(right: 15),
  132. showLeftIcon: false,
  133. textInputType: TextInputType.number,
  134. textInputAction: TextInputAction.next,
  135. onSubmit: (formKey, value) {
  136. state.formData[formKey]!['focusNode'].unfocus();
  137. },
  138. ).expanded(),
  139. ],
  140. )
  141. ],
  142. )).expanded(),
  143. //底部按钮
  144. MyButton(
  145. onPressed: viewModel.addCard,
  146. text: S.current.add_card,
  147. textColor: Colors.white,
  148. backgroundColor: context.appColors.btnBgDefault,
  149. fontWeight: FontWeight.w500,
  150. type: ClickType.throttle,
  151. fontSize: 16,
  152. minHeight: 50,
  153. radius: 0,
  154. ),
  155. ],
  156. ),
  157. ),
  158. );
  159. }
  160. Widget _buildInputLayout(
  161. BuildContext context,
  162. AddCardState state,
  163. String key, {
  164. EdgeInsetsGeometry? margin,
  165. bool showRightIcon = false, //是否展示右侧的布局
  166. bool showLeftIcon = true, //是否展示左侧侧的布局
  167. Widget? rightWidget, //右侧的布局
  168. TextInputType textInputType = TextInputType.text,
  169. String? leftIcon,
  170. String? errorText,
  171. bool obscureText = false,
  172. TextInputAction textInputAction = TextInputAction.done,
  173. Function? onSubmit,
  174. }) {
  175. return IgnoreKeyboardDismiss(
  176. child: MyTextField(
  177. key,
  178. fillBackgroundColor: context.appColors.authFiledBG,
  179. state.formData[key]!['value'],
  180. hintText: state.formData[key]!['hintText'],
  181. hintStyle: TextStyle(
  182. color: context.appColors.authFiledHintDark,
  183. fontSize: 16.0,
  184. fontWeight: FontWeight.w400,
  185. ),
  186. controller: state.formData[key]!['controller'],
  187. focusNode: state.formData[key]!['focusNode'],
  188. margin: margin ?? EdgeInsets.zero,
  189. padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 3),
  190. showDivider: false,
  191. height: 44,
  192. style: TextStyle(
  193. color: context.appColors.authFiledText,
  194. fontSize: 16.0,
  195. fontWeight: FontWeight.w400,
  196. ),
  197. inputType: textInputType,
  198. textInputAction: textInputAction,
  199. onSubmit: onSubmit,
  200. cursorColor: context.appColors.authFiledText,
  201. obscureText: obscureText,
  202. errorText: errorText,
  203. showLeftIcon: showLeftIcon,
  204. leftWidget: showLeftIcon
  205. ? MyAssetImage(
  206. leftIcon ?? "",
  207. width: 27,
  208. height: 27,
  209. color: DarkThemeUtil.multiColors(context, AppColorsTheme.colorPrimary, darkColor: Colors.white),
  210. )
  211. : const SizedBox(),
  212. showRightIcon: showRightIcon,
  213. rightWidget: rightWidget,
  214. ),
  215. );
  216. }
  217. }