my_text_form_field.dart 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. import 'dart:async';
  2. import 'dart:core';
  3. import 'package:cs_resources/constants/color_constants.dart';
  4. import 'package:flutter/material.dart';
  5. import 'package:get/get_utils/src/extensions/widget_extensions.dart';
  6. import 'ext/ex_widget.dart';
  7. import 'utils/dark_theme_util.dart';
  8. /*
  9. * Form表单内部的输入框的封装
  10. */
  11. class MyTextFormField extends StatelessWidget {
  12. String formKey;
  13. String value;
  14. bool? enabled;
  15. TextInputType inputType;
  16. String? labelText;
  17. TextStyle? labelStyle;
  18. String? errorText;
  19. double cursorWidth;
  20. Color? cursorColor = ColorConstants.appBlue;
  21. String? hintText;
  22. String? initialValue;
  23. TextStyle? hintStyle;
  24. TextStyle? style;
  25. bool? autofocus;
  26. int? maxLines = 1;
  27. InputBorder? border;
  28. BoxBorder? boxBorder;
  29. bool? showLeftIcon;
  30. Widget? leftWidget;
  31. bool? showRightIcon;
  32. Widget? rightWidget;
  33. bool? showDivider;
  34. Color? dividerColor;
  35. bool obscureText;
  36. double height;
  37. Color? fillBackgroundColor;
  38. double? fillCornerRadius;
  39. EdgeInsetsGeometry padding;
  40. EdgeInsetsGeometry margin;
  41. InputDecoration? decoration;
  42. TextInputAction textInputAction = TextInputAction.done;
  43. Function? onChanged;
  44. Function? onSubmit;
  45. String? Function(String? value)? onSaved; //Form表单的保存
  46. String? Function(String? value)? validator; //Form表单的校验
  47. final ClickType changeActionType; //默认没有点击类型
  48. final int changeActionMilliseconds; //点击类型的时间戳(毫秒)
  49. final ClickType submitActionType; //默认没有点击类型
  50. final int submitActionMilliseconds; //点击类型的时间戳(毫秒)
  51. MyTextFormField(
  52. this.formKey,
  53. this.value, {
  54. Key? key,
  55. this.enabled = true, //是否可用
  56. this.inputType = TextInputType.text, //输入类型
  57. this.initialValue, //初始化文本
  58. this.labelText,
  59. this.labelStyle,
  60. this.errorText, //错误的文本
  61. this.cursorWidth = 2.0, // 光标宽度
  62. this.cursorColor, // 光标颜色
  63. this.hintText, //提示文本
  64. this.hintStyle, //提示文本样式
  65. this.style, //默认的文本样式
  66. this.autofocus = false, // 自动聚焦
  67. this.maxLines = 1, //最多行数,高度与行数同步
  68. this.border = InputBorder.none, //TextFiled的边框
  69. this.boxBorder, // 外层Container的边框
  70. this.showLeftIcon = false, //是否展示左侧的布局
  71. this.leftWidget, //左侧的布局
  72. this.showRightIcon = false, //是否展示右侧的布局
  73. this.rightWidget, //右侧的布局
  74. this.showDivider = true, // 是否显示下分割线
  75. this.dividerColor = const Color.fromARGB(255, 212, 212, 212), // 下分割线颜色
  76. this.obscureText = false, //是否隐藏文本,即显示密码类型
  77. this.height = 50.0,
  78. this.fillBackgroundColor, //整体的背景颜色
  79. this.fillCornerRadius, //整体的背景颜色圆角
  80. this.padding = EdgeInsets.zero, //整体布局的Padding
  81. this.margin = EdgeInsets.zero, //整体布局的Margin
  82. this.decoration, //自定义装饰
  83. this.textInputAction = TextInputAction.done, //默认的行为是Done(完成)
  84. this.validator, //Form验证
  85. this.onSaved, //Form保存
  86. this.onChanged, //输入改变回调
  87. this.onSubmit, //完成行为的回调(默认行为是Done完成)
  88. this.changeActionType = ClickType.none, //默认没有点击类型
  89. this.changeActionMilliseconds = 500, //回调类型的时间戳(毫秒)
  90. this.submitActionType = ClickType.none, //默认没有点击类型
  91. this.submitActionMilliseconds = 500, //回调类型的时间戳(毫秒)
  92. }) : super(key: key);
  93. @override
  94. Widget build(BuildContext context) {
  95. //抽取的改变的回调
  96. changeAction(value) {
  97. onChanged?.call(formKey, value);
  98. }
  99. //抽取的提交的回调
  100. submitAction(value) {
  101. onSubmit?.call(formKey, value);
  102. }
  103. return Container(
  104. margin: margin,
  105. decoration: BoxDecoration(
  106. color: fillBackgroundColor ?? Colors.transparent,
  107. borderRadius: BorderRadius.all(Radius.circular(fillCornerRadius ?? 0)),
  108. border: boxBorder,
  109. ),
  110. padding: padding,
  111. child: ConstrainedBox(
  112. constraints: BoxConstraints(minHeight: height),
  113. child: Column(
  114. mainAxisAlignment: maxLines == null ? MainAxisAlignment.start : MainAxisAlignment.center,
  115. children: [
  116. TextFormField(
  117. enabled: enabled,
  118. style: style,
  119. maxLines: maxLines,
  120. keyboardType: inputType,
  121. obscureText: obscureText,
  122. cursorWidth: cursorWidth,
  123. cursorColor: DarkThemeUtil.multiColors(cursorColor, darkColor: Colors.white),
  124. autofocus: autofocus!,
  125. validator: validator,
  126. decoration: decoration ??
  127. InputDecoration(
  128. hintText: hintText,
  129. hintStyle: hintStyle,
  130. icon: showLeftIcon == true ? leftWidget : null,
  131. border: border,
  132. suffixIcon: showRightIcon == true ? rightWidget : null,
  133. labelText: labelText,
  134. errorText: errorText,
  135. errorStyle: const TextStyle(color: Colors.red, fontSize: 11.5),
  136. errorBorder: const OutlineInputBorder(
  137. borderSide: BorderSide(color: Colors.red),
  138. ),
  139. ),
  140. onChanged: changeActionType == ClickType.debounce
  141. ? debounce(changeAction, changeActionMilliseconds)
  142. : changeActionType == ClickType.throttle
  143. ? throttle(changeAction, changeActionMilliseconds)
  144. : changeAction,
  145. onFieldSubmitted: submitActionType == ClickType.debounce
  146. ? debounce(submitAction, submitActionMilliseconds)
  147. : submitActionType == ClickType.throttle
  148. ? throttle(submitAction, submitActionMilliseconds)
  149. : submitAction,
  150. onSaved: onSaved,
  151. textInputAction: textInputAction,
  152. ),
  153. showDivider == true
  154. ? Divider(
  155. height: 0.5,
  156. color: dividerColor!,
  157. ).marginOnly(top: errorText == null ? 0 : 10)
  158. : const SizedBox.shrink(),
  159. ],
  160. ),
  161. ),
  162. );
  163. }
  164. //带参数的函数防抖,由于参数不固定就没有用过扩展,直接用方法包裹
  165. void Function(String value) debounce(void Function(String value) callback, [int milliseconds = 500]) {
  166. Timer? _debounceTimer;
  167. return (value) {
  168. if (_debounceTimer?.isActive ?? false) _debounceTimer?.cancel();
  169. _debounceTimer = Timer(Duration(milliseconds: milliseconds), () {
  170. callback(value);
  171. });
  172. };
  173. }
  174. //带参数的函数节流,由于参数不固定就没有用过扩展,直接用方法包裹
  175. void Function(String value) throttle(void Function(String value) callback, [int milliseconds = 500]) {
  176. bool _isAllowed = true;
  177. Timer? _throttleTimer;
  178. return (value) {
  179. if (!_isAllowed) return;
  180. _isAllowed = false;
  181. callback(value);
  182. _throttleTimer?.cancel();
  183. _throttleTimer = Timer(Duration(milliseconds: milliseconds), () {
  184. _isAllowed = true;
  185. });
  186. };
  187. }
  188. }