mobile_skt/lib/widgets/form_item/sk_number_input.dart

130 lines
4.0 KiB
Dart

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<T> 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<T>? 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<SkNumberInput> createState() => _SkNumberInputState<T>();
}
class _SkNumberInputState<T> extends State<SkNumberInput> {
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: <TextInputFormatter>[
// 限制输入内容只能是数字和小数点不限制位数
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 ?? '请输入',
),
);
}
}