首先尝试了解 Dart 中的 null 安全性:https://dart.dev/null-safety
要指示参数可能具有 null 值,只需添加 ?对其类型声明:
final String? hintText;
final double? verticalPadding;
final String? value;
final Icon? suffixIcon;
final bool? showLabel;
CustomTextFormField(
{this.hintText, this.verticalPadding, this.value, this.suffixIcon, this.showLabel = true});
在数据类型之后添加 (?) 可空运算符意味着您的参数可以为空 & 是可选的,当您调用 CommonTextFormField() 时,它们不需要传递任何值。
如果在数据类型之后不添加 (?) 可为空,则构造函数参数中需要所有字段
像这样:
final String hintText;
final double verticalPadding;
final String value;
final Icon suffixIcon;
final bool showLabel;
CustomTextFormField(
{required this.hintText, required this.verticalPadding,required this.value,required this.suffixIcon,required this.showLabel});
命名参数是可选的,除非它们被明确标记为必需。
试试这个代码(包括密码、手机、电子邮件验证):
class CommonTextFormField extends StatelessWidget {
const CommonTextFormField(
{Key? key,
this.focusNode,
this.height,
this.maxLength,
this.maxLines,
this.textInputAction,
required this.hintText,
this.controller,
this.readOnly,
this.isImportantStarLabelRequired,
this.obscureText,
this.isFixedlabel,
this.isDense,
this.onSubmittedRequired,
this.autofocus,
this.isSuffixIconRequired,
this.keyboardType,
this.onChanged,
this.onTap,
this.suffixIcon,
this.labelHeading,
this.inputFormatters,
this.errorText,
this.isfilled = false,
this.textAlign,
this.textAlignVertical,
this.hintStyle,
this.customDateError,
this.isMobileValidationRequired,
this.isEmailValidationRequired,
this.isPasswordValidationRequired,
this.compareWithcontroller,
this.compareWithPrevious = false,
this.compareErrorText})
: super(key: key);
final FocusNode? focusNode;
final TextAlign? textAlign;
final TextAlignVertical? textAlignVertical;
final TextStyle? hintStyle;
final double? height;
final int? maxLength;
final int? maxLines;
final TextInputAction? textInputAction;
final String hintText;
final String? errorText;
final String? compareErrorText;
final TextEditingController? controller;
final TextEditingController? compareWithcontroller;
final bool? readOnly;
final bool? isImportantStarLabelRequired;
final bool? obscureText;
final bool? isFixedlabel;
final bool? isDense;
final bool? onSubmittedRequired;
final bool? isfilled;
final bool? isMobileValidationRequired;
final bool? isEmailValidationRequired;
final bool? isPasswordValidationRequired;
final bool? customDateError;
final bool? autofocus;
final bool? compareWithPrevious;
final bool? isSuffixIconRequired;
final TextInputType? keyboardType;
final void Function(String)? onChanged;
final void Function()? onTap;
final Widget? suffixIcon;
final String? labelHeading;
final List<TextInputFormatter>? inputFormatters;
@override
Widget build(BuildContext context) {
final themeViewModel = context.watch<ThemeViewModel>();
final baseTextTheme = themeViewModel.baseTextTheme;
final baseColorTheme = themeViewModel.colors;
bool error = false;
return TextFormField(
autovalidateMode: AutovalidateMode.onUserInteraction,
autofocus: autofocus ?? false,
focusNode: focusNode,
maxLength: maxLength,
maxLines: maxLines ?? 1,
readOnly: readOnly ?? false,
onTap: onTap,
keyboardType: keyboardType ?? TextInputType.text,
textInputAction: textInputAction ?? TextInputAction.next,
controller: controller,
obscureText: obscureText ?? false,
inputFormatters: inputFormatters,
onChanged: onChanged,
onFieldSubmitted: onSubmittedRequired == true
? (_) => FocusScope.of(context).nextFocus()
: null,
style: baseTextTheme.hintValueTextStyle,
textCapitalization: TextCapitalization.sentences,
textAlign: textAlign ?? TextAlign.start,
textAlignVertical: textAlignVertical,
decoration: InputDecoration(
// fillColor: baseColorTheme.primaryColor,
// focusColor: Colors.white,
errorMaxLines: 2,
contentPadding:
const EdgeInsets.symmetric(horizontal: 10, vertical: 12),
suffixIcon: isSuffixIconRequired == true ? suffixIcon : null,
suffixIconConstraints:
const BoxConstraints(minWidth: 20, minHeight: 20),
// helperText: " ",
// helperStyle: const TextStyle(fontSize: 0),
isDense: true,
hintText: hintText,
hintStyle: hintStyle ?? baseTextTheme.loginTextFieldHintTextStyle,
errorStyle: TextStyle(
fontSize: 13,
fontFamily: 'Avenir',
color: baseColorTheme.textFieldFloatingLabelStarColor),
// errorStyle: focusNode.hasFocus
// ? const TextStyle(fontSize: 0, height: 0)
// : TextStyle(
// fontSize: 13,
// fontFamily: 'Avenir',
// color: baseColorTheme.textFieldFloatingLabelStarColor),
floatingLabelBehavior:
isFixedlabel == true ? FloatingLabelBehavior.always : null,
label: labelHeading != null
? RichText(
text: TextSpan(children: [
TextSpan(
text: labelHeading,
style: baseTextTheme.loginTextFieldFloatingLabelTextStyle,
),
if (isImportantStarLabelRequired == true)
TextSpan(
text: " *",
style: baseTextTheme
.loginTextFieldFloatingLabelStarTextStyle),
]))
: null,
focusedErrorBorder: OutlineInputBorder(
borderSide: BorderSide(
color: baseColorTheme.textFieldFloatingLabelStarColor)),
errorBorder: (controller != null && controller!.text.isNotEmpty)
? null
: OutlineInputBorder(
borderSide: BorderSide(
color: baseColorTheme.textFieldFloatingLabelStarColor)),
focusedBorder: const OutlineInputBorder(
borderSide: BorderSide(color: Colors.black)),
enabledBorder: OutlineInputBorder(
borderSide:
BorderSide(color: baseColorTheme.textfieldInputBorderColor)),
border: OutlineInputBorder(
borderSide:
BorderSide(color: baseColorTheme.textfieldInputBorderColor))),
validator: (value) {
value!.trim().isNotEmpty ? error = !error : error = error;
if (customDateError == true) {
if (value.toLowerCase() == hintText.toLowerCase()) {
return errorText;
}
}
if (value.isEmpty) {
return errorText;
}
if (compareWithPrevious == true) {
if (compareWithcontroller != null) {
if (value != compareWithcontroller!.text) {
return compareErrorText ??
'Make sure your field matches with above';
}
}
}
if (isMobileValidationRequired == true) {
if (value.length > 10 || value.length < 10) {
return "Please Enter Valid Mobile Number";
}
}
if (isEmailValidationRequired == true) {
if (!RegExp(
r'^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$')
.hasMatch(value)) {
return "Please Enter Valid Email ID";
}
}
if (isPasswordValidationRequired == true) {
if (!RegExp(
r'^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[!@#\$&*~]).{6,}$')
.hasMatch(value)) {
return "Please enter a strong password of atleast 6 characters ( for eg. Name@1234 )";
}
}
return null;
},
);
}
}