my_text_form_field.dart 7.2 KB

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