import 'dart:async'; import 'dart:core'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:cs_resources/constants/color_constants.dart'; import 'ext/ex_widget.dart'; import 'utils/dark_theme_util.dart'; // ignore: slash_for_doc_comments /** 输入框的封装 */ class MyTextField extends StatelessWidget { String formKey; String value; bool? enabled; TextInputType inputType; FocusNode? focusNode; String? labelText; TextStyle? labelStyle; String? errorText; double cursorWidth; Color? cursorColor = ColorConstants.appBlue; String? hintText; TextStyle? hintStyle; TextStyle? style; bool? autofocus; int? maxLines = 1; InputBorder? border; BoxBorder? boxBorder; bool? showLeftIcon; Widget? leftWidget; bool? showRightIcon; Widget? rightWidget; bool? showDivider; Color? dividerColor; bool obscureText; double height; Color? fillBackgroundColor; double? fillCornerRadius; EdgeInsetsGeometry padding; EdgeInsetsGeometry margin; InputDecoration? decoration; TextEditingController? controller; TextInputAction textInputAction = TextInputAction.done; List? inputFormatters; Function? onChanged; Function? onSubmit; final ClickType changeActionType; //默认没有点击类型 final int changeActionMilliseconds; //点击类型的时间戳(毫秒) final ClickType submitActionType; //默认没有点击类型 final int submitActionMilliseconds; //点击类型的时间戳(毫秒) MyTextField( this.formKey, this.value, { Key? key, this.enabled = true, //是否可用 this.inputType = TextInputType.text, //输入类型 this.focusNode, //焦点 this.labelText, this.labelStyle, this.errorText, //错误的文本 this.cursorWidth = 2.0, // 光标宽度 this.cursorColor, // 光标颜色 this.hintText, //提示文本 this.hintStyle, //提示文本样式 this.style, //默认的文本样式 this.autofocus = false, // 自动聚焦 this.maxLines = 1, //最多行数,高度与行数同步 this.border = InputBorder.none, //TextFiled的边框 this.boxBorder, // 外层Container的边框 this.showLeftIcon = false, //是否展示左侧的布局 this.leftWidget, //左侧的布局 this.showRightIcon = false, //是否展示右侧的布局 this.rightWidget, //右侧的布局 this.showDivider = true, // 是否显示下分割线 this.dividerColor = const Color.fromARGB(255, 212, 212, 212), // 下分割线颜色 this.obscureText = false, //是否隐藏文本,即显示密码类型 this.height = 50.0, this.fillBackgroundColor, //整体的背景颜色 this.fillCornerRadius = 5.0, //整体的背景颜色圆角 this.padding = EdgeInsets.zero, //整体布局的Padding this.margin = EdgeInsets.zero, //整体布局的Margin this.decoration, //自定义装饰 this.controller, //控制器 this.inputFormatters, //输入格式控制 this.textInputAction = TextInputAction.done, //默认的行为是Done(完成) this.onChanged, //输入改变回调 this.onSubmit, //完成行为的回调(默认行为是Done完成) this.changeActionType = ClickType.none, //默认没有点击类型 this.changeActionMilliseconds = 500, //回调类型的时间戳(毫秒) this.submitActionType = ClickType.none, //默认没有点击类型 this.submitActionMilliseconds = 500, //回调类型的时间戳(毫秒) }) : super(key: key); @override Widget build(BuildContext context) { //抽取的改变的回调 changeAction(value) { onChanged?.call(formKey, value); } //抽取的提交的回调 submitAction(value) { onSubmit?.call(formKey, value); } return Container( margin: margin, decoration: BoxDecoration( color: fillBackgroundColor ?? Colors.transparent, borderRadius: BorderRadius.all(Radius.circular(fillCornerRadius ?? 0)), border: boxBorder, ), padding: padding, child: ConstrainedBox( constraints: BoxConstraints(minHeight: height), child: Column( mainAxisAlignment: maxLines == null ? MainAxisAlignment.start : MainAxisAlignment.center, children: [ TextField( enabled: enabled, style: style, maxLines: maxLines, keyboardType: inputType, focusNode: focusNode, obscureText: obscureText, cursorWidth: cursorWidth, cursorColor: DarkThemeUtil.multiColors(context, cursorColor, darkColor: Colors.white), autofocus: autofocus!, controller: controller, inputFormatters: inputFormatters, decoration: decoration ?? InputDecoration( hintText: hintText, hintStyle: hintStyle, icon: showLeftIcon == true ? leftWidget : null, border: border, suffixIcon: showRightIcon == true ? rightWidget : null, labelText: labelText, errorText: errorText, errorStyle: const TextStyle(color: Colors.redAccent, fontSize: 11.5, height: 0.5), errorBorder: const OutlineInputBorder( borderSide: BorderSide(color: Colors.redAccent), ), ), onChanged: changeActionType == ClickType.debounce ? debounce(changeAction, changeActionMilliseconds) : changeActionType == ClickType.throttle ? throttle(changeAction, changeActionMilliseconds) : changeAction, onSubmitted: submitActionType == ClickType.debounce ? debounce(submitAction, submitActionMilliseconds) : submitActionType == ClickType.throttle ? throttle(submitAction, submitActionMilliseconds) : submitAction, textInputAction: textInputAction, ), showDivider == true ? Divider( height: 0.3, color: dividerColor!, ).marginOnly(top: errorText == null ? 0 : 10) : const SizedBox.shrink(), ], ), ), ); } //带参数的函数防抖,由于参数不固定就没有用过扩展,直接用方法包裹 void Function(String value) debounce(void Function(String value) callback, [int milliseconds = 500]) { Timer? _debounceTimer; return (value) { if (_debounceTimer?.isActive ?? false) _debounceTimer?.cancel(); _debounceTimer = Timer(Duration(milliseconds: milliseconds), () { callback(value); }); }; } //带参数的函数节流,由于参数不固定就没有用过扩展,直接用方法包裹 void Function(String value) throttle(void Function(String value) callback, [int milliseconds = 500]) { bool _isAllowed = true; Timer? _throttleTimer; return (value) { if (!_isAllowed) return; _isAllowed = false; callback(value); _throttleTimer?.cancel(); _throttleTimer = Timer(Duration(milliseconds: milliseconds), () { _isAllowed = true; }); }; } }