import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:sk_base_mobile/app_theme.dart'; import 'package:sk_base_mobile/util/screen_adaper_util.dart'; class SkNumberInput extends StatefulWidget { final TextEditingController textController; final Function(FocusNode)? onTap; final Function(String)? onChanged; final void Function(dynamic)? onTapOutside; final Function(dynamic)? validator; final bool isDense; final EdgeInsetsGeometry? contentPadding; final bool autoFocus; final bool isRequired; final String labelText; final String? hint; final ValueChanged? onFieldSubmitted; const SkNumberInput( {super.key, required this.textController, this.onTap, this.onChanged, this.hint, this.onTapOutside, this.isRequired = false, this.labelText = '', this.onFieldSubmitted, this.autoFocus = false, this.contentPadding, this.isDense = false, this.validator}); @override State createState() => _SkNumberInputState(); } class _SkNumberInputState extends State { late FocusNode focusNode = FocusNode(); @override void initState() { super.initState(); if (widget.autoFocus) { WidgetsBinding.instance.addPostFrameCallback((_) { focusNode.requestFocus(); }); } } @override Widget build(BuildContext context) { return TextFormField( focusNode: focusNode, onTap: () { if (widget.onTap != null) { widget.onTap!(focusNode); } }, controller: widget.textController, onFieldSubmitted: (event) { if (widget.onTapOutside != null) { dynamic value; if (T == double) { value = double.tryParse(widget.textController.text); widget.onTapOutside!(value as T); } else { value = int.tryParse(widget.textController.text); } if (widget.validator != null && !widget.validator!(value)) { return; } widget.onTapOutside!(value as T); } }, onTapOutside: (event) { if (widget.onTapOutside != null) { dynamic value = widget.textController.text; if (T == double) { value = double.tryParse(widget.textController.text) ?? 0.0; widget.onTapOutside!(value as T); } else { value = int.tryParse(widget.textController.text) ?? 0; } if (widget.validator != null && !widget.validator!(value)) { return; } widget.onTapOutside!(value as T); FocusScope.of(context).unfocus(); } }, onChanged: widget.onChanged ?? (_) {}, textAlign: TextAlign.center, keyboardType: TextInputType.number, inputFormatters: [ // 限制输入内容只能是数字和小数点不限制位数 FilteringTextInputFormatter.allow(RegExp(r'^\d+\.?\d{0,10}')), ], decoration: InputDecoration( contentPadding: widget.contentPadding, isDense: widget.isDense, // contentPadding: EdgeInsets.symmetric(vertical: ScreenAdaper.height(18)), floatingLabelBehavior: FloatingLabelBehavior.always, label: Row( crossAxisAlignment: CrossAxisAlignment.center, mainAxisSize: MainAxisSize.min, children: [ if (widget.isRequired) Text( "*", style: TextStyle( color: Colors.red, fontSize: ScreenAdaper.height(30)), ), Text( widget.labelText, style: TextStyle(fontSize: ScreenAdaper.height(30)), ), ]), focusedBorder: OutlineInputBorder( borderSide: const BorderSide(color: AppTheme.primaryColorLight, width: 2), borderRadius: BorderRadius.circular(ScreenAdaper.sp(15))), hintText: widget.hint ?? '请输入', ), ); } }