颤动输入中只允许两位小数吗?
Allow only two decimal number in flutter input?
我只想要flutter输入的小数点后两位数。用户不能在小数点后添加超过两位数。
给你!
希望对您有所帮助:)
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'dart:math' as math;
void main() {
runApp(new MaterialApp(home: new MyApp()));
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Flutter"),
),
body: Form(
child: ListView(
children: <Widget>[
TextFormField(
inputFormatters: [DecimalTextInputFormatter(decimalRange: 2)],
keyboardType: TextInputType.numberWithOptions(decimal: true),
)
],
),
),
);
}
}
class DecimalTextInputFormatter extends TextInputFormatter {
DecimalTextInputFormatter({this.decimalRange})
: assert(decimalRange == null || decimalRange > 0);
final int decimalRange;
@override
TextEditingValue formatEditUpdate(
TextEditingValue oldValue, // unused.
TextEditingValue newValue,
) {
TextSelection newSelection = newValue.selection;
String truncated = newValue.text;
if (decimalRange != null) {
String value = newValue.text;
if (value.contains(".") &&
value.substring(value.indexOf(".") + 1).length > decimalRange) {
truncated = oldValue.text;
newSelection = oldValue.selection;
} else if (value == ".") {
truncated = "0.";
newSelection = newValue.selection.copyWith(
baseOffset: math.min(truncated.length, truncated.length + 1),
extentOffset: math.min(truncated.length, truncated.length + 1),
);
}
return TextEditingValue(
text: truncated,
selection: newSelection,
composing: TextRange.empty,
);
}
return newValue;
}
}
我扩展了功能...我希望你能觉得它有用。请告诉我您是否可以进一步改进。
import 'package:flutter/services.dart';
import 'dart:math' as math;
class DecimalTextInputFormatter extends TextInputFormatter {
DecimalTextInputFormatter({this.decimalRange, this.activatedNegativeValues})
: assert(decimalRange == null || decimalRange >= 0,
'DecimalTextInputFormatter declaretion error');
final int decimalRange;
final bool activatedNegativeValues;
@override
TextEditingValue formatEditUpdate(
TextEditingValue oldValue, // unused.
TextEditingValue newValue,
) {
TextSelection newSelection = newValue.selection;
String truncated = newValue.text;
if (newValue.text.contains(' ')) {
return oldValue;
}
if (newValue.text.isEmpty) {
return newValue;
} else if (double.tryParse(newValue.text) == null &&
!(newValue.text.length == 1 &&
(activatedNegativeValues == true ||
activatedNegativeValues == null) &&
newValue.text == '-')) {
return oldValue;
}
if (activatedNegativeValues == false &&
double.tryParse(newValue.text) < 0) {
return oldValue;
}
if (decimalRange != null) {
String value = newValue.text;
if (decimalRange == 0 && value.contains(".")) {
truncated = oldValue.text;
newSelection = oldValue.selection;
}
if (value.contains(".") &&
value.substring(value.indexOf(".") + 1).length > decimalRange) {
truncated = oldValue.text;
newSelection = oldValue.selection;
} else if (value == ".") {
truncated = "0.";
newSelection = newValue.selection.copyWith(
baseOffset: math.min(truncated.length, truncated.length + 1),
extentOffset: math.min(truncated.length, truncated.length + 1),
);
}
return TextEditingValue(
text: truncated,
selection: newSelection,
composing: TextRange.empty,
);
}
return newValue;
}
}
使用 Regexp 的 DecimalTextInputFormatter 的较短版本:
class DecimalTextInputFormatter extends TextInputFormatter {
DecimalTextInputFormatter({int decimalRange, bool activatedNegativeValues})
: assert(decimalRange == null || decimalRange >= 0,
'DecimalTextInputFormatter declaretion error') {
String dp = (decimalRange != null && decimalRange > 0) ? "([.][0-9]{0,$decimalRange}){0,1}" : "";
String num = "[0-9]*$dp";
if(activatedNegativeValues) {
_exp = new RegExp("^((((-){0,1})|((-){0,1}[0-9]$num))){0,1}$");
}
else {
_exp = new RegExp("^($num){0,1}$");
}
}
RegExp _exp;
@override
TextEditingValue formatEditUpdate(
TextEditingValue oldValue,
TextEditingValue newValue,
) {
if(_exp.hasMatch(newValue.text)){
return newValue;
}
return oldValue;
}
}
@AjayKumar 的回答允许将文本输入限制为所需的小数 places.But 我的要求是避免键盘输入除数字和 dot.So 之外的其他字符,我更新了 @AjayKumar 的上述回答
import 'package:flutter/services.dart';
import 'dart:math' as math;
class DecimalTextInputFormatter extends TextInputFormatter {
DecimalTextInputFormatter({this.decimalRange})
: assert(decimalRange == null || decimalRange > 0);
final int decimalRange;
@override
TextEditingValue formatEditUpdate(
TextEditingValue oldValue, // unused.
TextEditingValue newValue,
) {
TextSelection newSelection = newValue.selection;
String truncated = newValue.text;
if (decimalRange != null) {
String value = newValue.text;
if (value.contains(',') ||
value.contains('-') ||
value.contains(' ') ||
value.contains('..')) {
truncated = oldValue.text;
newSelection = oldValue.selection;
} else if (value.contains(".") &&
value.substring(value.indexOf(".") + 1).length > decimalRange) {
truncated = oldValue.text;
newSelection = oldValue.selection;
} else if (value == ".") {
truncated = "0.";
newSelection = newValue.selection.copyWith(
baseOffset: math.min(truncated.length, truncated.length + 1),
extentOffset: math.min(truncated.length, truncated.length + 1),
);
}
return TextEditingValue(
text: truncated,
selection: newSelection,
composing: TextRange.empty,
);
}
return newValue;
}
}
也许对你来说有点晚了,但我也进步了一点:
- 只允许 1
.
- 允许否定
- 开头加负号
希望对您有所帮助 ;)
import 'package:flutter/services.dart';
class NumberTextInputFormatter extends TextInputFormatter {
NumberTextInputFormatter({this.decimalRange}) : assert(decimalRange == null || decimalRange > 0);
final int decimalRange;
@override
TextEditingValue formatEditUpdate(TextEditingValue oldValue, TextEditingValue newValue) {
TextEditingValue _newValue = this.sanitize(newValue);
String text = _newValue.text;
if (decimalRange == null) {
return _newValue;
}
if (text == '.') {
return TextEditingValue(
text: '0.',
selection: _newValue.selection.copyWith(baseOffset: 2, extentOffset: 2),
composing: TextRange.empty,
);
}
return this.isValid(text) ? _newValue : oldValue;
}
bool isValid(String text) {
int dots = '.'.allMatches(text).length;
if (dots == 0) {
return true;
}
if (dots > 1) {
return false;
}
return text.substring(text.indexOf('.') + 1).length <= decimalRange;
}
TextEditingValue sanitize(TextEditingValue value) {
if (false == value.text.contains('-')) {
return value;
}
String text = '-' + value.text.replaceAll('-', '');
return TextEditingValue(text: text, selection: value.selection, composing: TextRange.empty);
}
}
和(别忘了导入前面的class)
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
class NumberFormField extends StatelessWidget {
final InputDecoration decoration;
final TextEditingController controller;
final int decimalRange;
const NumberFormField({Key key, this.decoration, this.controller, this.decimalRange}) :super(key: key);
@override
Widget build(BuildContext context) {
return TextFormField(
decoration: this.decoration,
controller: this.controller,
keyboardType: TextInputType.numberWithOptions(decimal: true),
inputFormatters: [
WhitelistingTextInputFormatter(RegExp(r'[\d+\-\.]')),
NumberTextInputFormatter(decimalRange: this.decimalRange),
],
);
}
}
并避免不必要的零...请调试此代码。
import 'dart:math' as math;
import 'package:flutter/services.dart';
class DecimalTextInputFormatter extends TextInputFormatter {
DecimalTextInputFormatter({this.decimalRange, this.activatedNegativeValues})
: assert(decimalRange == null || decimalRange >= 0,
'DecimalTextInputFormatter declaretion error');
final int decimalRange;
final bool activatedNegativeValues;
@override
TextEditingValue formatEditUpdate(
TextEditingValue oldValue, // unused.
TextEditingValue newValue,
) {
TextSelection newSelection = newValue.selection;
String truncated = newValue.text;
if (newValue.text.contains(' ')) {
return oldValue;
}
if (newValue.text.isEmpty) {
return newValue;
} else if (double.tryParse(newValue.text) == null &&
!(newValue.text.length == 1 &&
(activatedNegativeValues == true ||
activatedNegativeValues == null) &&
newValue.text == '-')) {
return oldValue;
}
if (activatedNegativeValues == false &&
double.tryParse(newValue.text) < 0) {
return oldValue;
}
if ((double.tryParse(oldValue.text) == 0 && !newValue.text.contains('.'))) {
if (newValue.text.length >= oldValue.text.length) {
return oldValue;
}
}
if (decimalRange != null) {
String value = newValue.text;
if (decimalRange == 0 && value.contains(".")) {
truncated = oldValue.text;
newSelection = oldValue.selection;
}
if (value.contains(".") &&
value.substring(value.indexOf(".") + 1).length > decimalRange) {
truncated = oldValue.text;
newSelection = oldValue.selection;
} else if (value == ".") {
truncated = "0.";
newSelection = newValue.selection.copyWith(
baseOffset: math.min(truncated.length, truncated.length + 1),
extentOffset: math.min(truncated.length, truncated.length + 1),
);
}
return TextEditingValue(
text: truncated,
selection: newSelection,
composing: TextRange.empty,
);
}
return newValue;
}
}
这是一个适合我的解决方案
TextFormField(
inputFormatters: [
WhitelistingTextInputFormatter(RegExp(r'^\d+\.?\d{0,2}')),
],
)
如果你想允许像 (.21) 或 (.25) 这样的输入
这里有一个解决方案-
TextFormField(
inputFormatters: [
WhitelistingTextInputFormatter(RegExp(r'^(\d+)?\.?\d{0,2}')),
],
)
可能这是一个更简单的解决方案
inputFormatters: [
FilteringTextInputFormatter.allow(RegExp(r'(^\d*\.?\d{0,2})'))
]
在 Flutter 版本 v1.20.0-1.0 之后。使用
TextFormField(
keyboardType: TextInputType.numberWithOptions(decimal: true),
inputFormatters: [
FilteringTextInputFormatter.allow(RegExp(r'^\d+\.?\d{0,2}')),
],
),
我认为这是最简单也是唯一适合我的方法:
inputFormatters: [ LengthLimitingTextInputFormatter(2), ]
飞镖 2.00+
TextFormField(
keyboardType: TextInputType.numberWithOptions(decimal: true),
inputFormatters: [
// Allow Decimal Number With Precision of 2 Only
FilteringTextInputFormatter.allow(RegExp(r'^\d*\.?\d{0,2}')),
],
它允许像 1.
、.89
、8.99
这样的小数
Dart SDK 版本:2.13.4(稳定)
Flutter 2.2.3 • 通道稳定
我在 2021 年 7 月 25 日写了这个答案,提出了一个更简单的解决方案,只使用内置 TextField 的 inputFormatters
。
我试图向你们所有人保证,该字段不会接受长于 2 的浮点数(已接受:12.25 与未接受:65.536)。而且,它不会接受多个点,只接受一个点(接受:12.25 vs notAccepted:1.1.11, 1.11, .1.1, 1.1.1.1, whatever..)。
考虑到其他答案的不同之处在于,下面的代码不会以编程方式接受等于 0.1
的 .1
,这实际上更加用户友好。它很简单,对我们来说很好看。您只需将下面的代码复制并粘贴到 inputFormatters: []
.
如果你想同时接受0.1
和.1
(不仅仅是0.1
),你可以注释掉FilteringTextInputFormatter.allow(RegExp(r'^\d+\.?\d*'))
!
inputFormatters: [ FilteringTextInputFormatter.allow(RegExp(r'^(\d+)?\.?\d{0,2}')), FilteringTextInputFormatter.allow(RegExp(r'^\d+\.?\d*')), ]
当你想改变最大小数点时,你可以改变下面一行中的N
值:
inputFormatters: [ FilteringTextInputFormatter.allow(RegExp(r'^(\d+)?\.?\d{0,N}')), FilteringTextInputFormatter.allow(RegExp(r'^\d+\.?\d*')), ]
第一个例子展示了你想限制小数点为2的情况,而N值恰好控制了这个限制。您可以在自己的代码中尝试 [:
感谢所有其他答案,希望这个答案可以帮助未来的流浪者!祝你有美好的一天[:
对于 Flutter 中的 TextFeild 小数点前和小数点后长度验证 class.
import 'package:flutter/cupertino.dart';
import 'package:flutter/services.dart';
import 'dart:math' as math;
class DecimalTextInputFormatter extends TextInputFormatter {
DecimalTextInputFormatter({this.decimalRange,this.beforeDecimalRange})
: assert(decimalRange == null || decimalRange > 0 || beforeDecimalRange == null || beforeDecimalRange > 0 );
final int decimalRange;
final int beforeDecimalRange;
@override
TextEditingValue formatEditUpdate(
TextEditingValue oldValue, // unused.
TextEditingValue newValue,
) {
TextSelection newSelection = newValue.selection;
String truncated = newValue.text;
String value;
if(beforeDecimalRange != null){
value = newValue.text;
if(value.contains(".")){
if(value.split(".")[0].length > beforeDecimalRange){
truncated = oldValue.text;
newSelection = oldValue.selection;
}
}else{
if(value.length > beforeDecimalRange){
truncated = oldValue.text;
newSelection = oldValue.selection;
}
}
}
if (decimalRange != null) {
value = newValue.text;
if (value.contains(".") &&
value.substring(value.indexOf(".") + 1).length > decimalRange) {
truncated = oldValue.text;
newSelection = oldValue.selection;
} else if (value == ".") {
truncated = "0.";
newSelection = newValue.selection.copyWith(
baseOffset: math.min(truncated.length, truncated.length + 1),
extentOffset: math.min(truncated.length, truncated.length + 1),
);
}
return TextEditingValue(
text: truncated,
selection: newSelection,
composing: TextRange.empty,
);
}
return newValue;
}
}
在文本字段中,
前任。小数点前 9 位和小数点后 2 位允许以下代码。
inputFormatters: [ FilteringTextInputFormatter.allow(RegExp(r'^\d+\.?\d{0,2}')),
DecimalTextInputFormatter(decimalRange: 2, beforeDecimalRange: 9)
],
keyboardType: TextInputType.numberWithOptions(decimal: true),
这对我有用 (Feb/2022)
将文本限制为 2 个小数点并且只有 1 个“.” (句点)
0 将自动添加到号码的开头,如果用户手动删除“.”之前的数字
PS:对答案稍作编辑
TextFormField
TextFormField(
autofocus: false,
keyboardType: TextInputType.number,
controller: controller,
inputFormatters: [
DecimalTextInputFormatter(decimalRange: 2),
],
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please add amount.';
}
return null;
},
DecimalTextInputFormatter
import 'package:flutter/services.dart';
import 'dart:math' as math;
class DecimalTextInputFormatter extends TextInputFormatter {
DecimalTextInputFormatter({required this.decimalRange})
: assert(decimalRange > 0);
final int decimalRange;
@override
TextEditingValue formatEditUpdate(
TextEditingValue oldValue,
TextEditingValue newValue,
) {
TextSelection newSelection = newValue.selection;
String truncated = newValue.text;
String value = newValue.text;
if (value.contains(".") &&
value.substring(value.indexOf(".") + 1).length > decimalRange) {
truncated = oldValue.text;
newSelection = oldValue.selection;
} else if (value == ".") {
truncated = "0.";
newSelection = newValue.selection.copyWith(
baseOffset: math.min(truncated.length, truncated.length + 1),
extentOffset: math.min(truncated.length, truncated.length + 1),
);
} else if (value.contains(".")) {
String tempValue = value.substring(value.indexOf(".") + 1);
if (tempValue.contains(".")) {
truncated = oldValue.text;
newSelection = oldValue.selection;
}
if (value.indexOf(".") == 0) {
truncated = "0" + truncated;
newSelection = newValue.selection.copyWith(
baseOffset: math.min(truncated.length, truncated.length + 1),
extentOffset: math.min(truncated.length, truncated.length + 1),
);
}
}
if (value.contains(" ") || value.contains("-")) {
truncated = oldValue.text;
newSelection = oldValue.selection;
}
return TextEditingValue(
text: truncated,
selection: newSelection,
composing: TextRange.empty,
);
}
}
我只想要flutter输入的小数点后两位数。用户不能在小数点后添加超过两位数。
给你! 希望对您有所帮助:)
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'dart:math' as math;
void main() {
runApp(new MaterialApp(home: new MyApp()));
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Flutter"),
),
body: Form(
child: ListView(
children: <Widget>[
TextFormField(
inputFormatters: [DecimalTextInputFormatter(decimalRange: 2)],
keyboardType: TextInputType.numberWithOptions(decimal: true),
)
],
),
),
);
}
}
class DecimalTextInputFormatter extends TextInputFormatter {
DecimalTextInputFormatter({this.decimalRange})
: assert(decimalRange == null || decimalRange > 0);
final int decimalRange;
@override
TextEditingValue formatEditUpdate(
TextEditingValue oldValue, // unused.
TextEditingValue newValue,
) {
TextSelection newSelection = newValue.selection;
String truncated = newValue.text;
if (decimalRange != null) {
String value = newValue.text;
if (value.contains(".") &&
value.substring(value.indexOf(".") + 1).length > decimalRange) {
truncated = oldValue.text;
newSelection = oldValue.selection;
} else if (value == ".") {
truncated = "0.";
newSelection = newValue.selection.copyWith(
baseOffset: math.min(truncated.length, truncated.length + 1),
extentOffset: math.min(truncated.length, truncated.length + 1),
);
}
return TextEditingValue(
text: truncated,
selection: newSelection,
composing: TextRange.empty,
);
}
return newValue;
}
}
我扩展了功能...我希望你能觉得它有用。请告诉我您是否可以进一步改进。
import 'package:flutter/services.dart';
import 'dart:math' as math;
class DecimalTextInputFormatter extends TextInputFormatter {
DecimalTextInputFormatter({this.decimalRange, this.activatedNegativeValues})
: assert(decimalRange == null || decimalRange >= 0,
'DecimalTextInputFormatter declaretion error');
final int decimalRange;
final bool activatedNegativeValues;
@override
TextEditingValue formatEditUpdate(
TextEditingValue oldValue, // unused.
TextEditingValue newValue,
) {
TextSelection newSelection = newValue.selection;
String truncated = newValue.text;
if (newValue.text.contains(' ')) {
return oldValue;
}
if (newValue.text.isEmpty) {
return newValue;
} else if (double.tryParse(newValue.text) == null &&
!(newValue.text.length == 1 &&
(activatedNegativeValues == true ||
activatedNegativeValues == null) &&
newValue.text == '-')) {
return oldValue;
}
if (activatedNegativeValues == false &&
double.tryParse(newValue.text) < 0) {
return oldValue;
}
if (decimalRange != null) {
String value = newValue.text;
if (decimalRange == 0 && value.contains(".")) {
truncated = oldValue.text;
newSelection = oldValue.selection;
}
if (value.contains(".") &&
value.substring(value.indexOf(".") + 1).length > decimalRange) {
truncated = oldValue.text;
newSelection = oldValue.selection;
} else if (value == ".") {
truncated = "0.";
newSelection = newValue.selection.copyWith(
baseOffset: math.min(truncated.length, truncated.length + 1),
extentOffset: math.min(truncated.length, truncated.length + 1),
);
}
return TextEditingValue(
text: truncated,
selection: newSelection,
composing: TextRange.empty,
);
}
return newValue;
}
}
使用 Regexp 的 DecimalTextInputFormatter 的较短版本:
class DecimalTextInputFormatter extends TextInputFormatter {
DecimalTextInputFormatter({int decimalRange, bool activatedNegativeValues})
: assert(decimalRange == null || decimalRange >= 0,
'DecimalTextInputFormatter declaretion error') {
String dp = (decimalRange != null && decimalRange > 0) ? "([.][0-9]{0,$decimalRange}){0,1}" : "";
String num = "[0-9]*$dp";
if(activatedNegativeValues) {
_exp = new RegExp("^((((-){0,1})|((-){0,1}[0-9]$num))){0,1}$");
}
else {
_exp = new RegExp("^($num){0,1}$");
}
}
RegExp _exp;
@override
TextEditingValue formatEditUpdate(
TextEditingValue oldValue,
TextEditingValue newValue,
) {
if(_exp.hasMatch(newValue.text)){
return newValue;
}
return oldValue;
}
}
@AjayKumar 的回答允许将文本输入限制为所需的小数 places.But 我的要求是避免键盘输入除数字和 dot.So 之外的其他字符,我更新了 @AjayKumar 的上述回答
import 'package:flutter/services.dart';
import 'dart:math' as math;
class DecimalTextInputFormatter extends TextInputFormatter {
DecimalTextInputFormatter({this.decimalRange})
: assert(decimalRange == null || decimalRange > 0);
final int decimalRange;
@override
TextEditingValue formatEditUpdate(
TextEditingValue oldValue, // unused.
TextEditingValue newValue,
) {
TextSelection newSelection = newValue.selection;
String truncated = newValue.text;
if (decimalRange != null) {
String value = newValue.text;
if (value.contains(',') ||
value.contains('-') ||
value.contains(' ') ||
value.contains('..')) {
truncated = oldValue.text;
newSelection = oldValue.selection;
} else if (value.contains(".") &&
value.substring(value.indexOf(".") + 1).length > decimalRange) {
truncated = oldValue.text;
newSelection = oldValue.selection;
} else if (value == ".") {
truncated = "0.";
newSelection = newValue.selection.copyWith(
baseOffset: math.min(truncated.length, truncated.length + 1),
extentOffset: math.min(truncated.length, truncated.length + 1),
);
}
return TextEditingValue(
text: truncated,
selection: newSelection,
composing: TextRange.empty,
);
}
return newValue;
} }
也许对你来说有点晚了,但我也进步了一点:
- 只允许 1
.
- 允许否定
- 开头加负号
希望对您有所帮助 ;)
import 'package:flutter/services.dart';
class NumberTextInputFormatter extends TextInputFormatter {
NumberTextInputFormatter({this.decimalRange}) : assert(decimalRange == null || decimalRange > 0);
final int decimalRange;
@override
TextEditingValue formatEditUpdate(TextEditingValue oldValue, TextEditingValue newValue) {
TextEditingValue _newValue = this.sanitize(newValue);
String text = _newValue.text;
if (decimalRange == null) {
return _newValue;
}
if (text == '.') {
return TextEditingValue(
text: '0.',
selection: _newValue.selection.copyWith(baseOffset: 2, extentOffset: 2),
composing: TextRange.empty,
);
}
return this.isValid(text) ? _newValue : oldValue;
}
bool isValid(String text) {
int dots = '.'.allMatches(text).length;
if (dots == 0) {
return true;
}
if (dots > 1) {
return false;
}
return text.substring(text.indexOf('.') + 1).length <= decimalRange;
}
TextEditingValue sanitize(TextEditingValue value) {
if (false == value.text.contains('-')) {
return value;
}
String text = '-' + value.text.replaceAll('-', '');
return TextEditingValue(text: text, selection: value.selection, composing: TextRange.empty);
}
}
和(别忘了导入前面的class)
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
class NumberFormField extends StatelessWidget {
final InputDecoration decoration;
final TextEditingController controller;
final int decimalRange;
const NumberFormField({Key key, this.decoration, this.controller, this.decimalRange}) :super(key: key);
@override
Widget build(BuildContext context) {
return TextFormField(
decoration: this.decoration,
controller: this.controller,
keyboardType: TextInputType.numberWithOptions(decimal: true),
inputFormatters: [
WhitelistingTextInputFormatter(RegExp(r'[\d+\-\.]')),
NumberTextInputFormatter(decimalRange: this.decimalRange),
],
);
}
}
并避免不必要的零...请调试此代码。
import 'dart:math' as math;
import 'package:flutter/services.dart';
class DecimalTextInputFormatter extends TextInputFormatter {
DecimalTextInputFormatter({this.decimalRange, this.activatedNegativeValues})
: assert(decimalRange == null || decimalRange >= 0,
'DecimalTextInputFormatter declaretion error');
final int decimalRange;
final bool activatedNegativeValues;
@override
TextEditingValue formatEditUpdate(
TextEditingValue oldValue, // unused.
TextEditingValue newValue,
) {
TextSelection newSelection = newValue.selection;
String truncated = newValue.text;
if (newValue.text.contains(' ')) {
return oldValue;
}
if (newValue.text.isEmpty) {
return newValue;
} else if (double.tryParse(newValue.text) == null &&
!(newValue.text.length == 1 &&
(activatedNegativeValues == true ||
activatedNegativeValues == null) &&
newValue.text == '-')) {
return oldValue;
}
if (activatedNegativeValues == false &&
double.tryParse(newValue.text) < 0) {
return oldValue;
}
if ((double.tryParse(oldValue.text) == 0 && !newValue.text.contains('.'))) {
if (newValue.text.length >= oldValue.text.length) {
return oldValue;
}
}
if (decimalRange != null) {
String value = newValue.text;
if (decimalRange == 0 && value.contains(".")) {
truncated = oldValue.text;
newSelection = oldValue.selection;
}
if (value.contains(".") &&
value.substring(value.indexOf(".") + 1).length > decimalRange) {
truncated = oldValue.text;
newSelection = oldValue.selection;
} else if (value == ".") {
truncated = "0.";
newSelection = newValue.selection.copyWith(
baseOffset: math.min(truncated.length, truncated.length + 1),
extentOffset: math.min(truncated.length, truncated.length + 1),
);
}
return TextEditingValue(
text: truncated,
selection: newSelection,
composing: TextRange.empty,
);
}
return newValue;
}
}
这是一个适合我的解决方案
TextFormField(
inputFormatters: [
WhitelistingTextInputFormatter(RegExp(r'^\d+\.?\d{0,2}')),
],
)
如果你想允许像 (.21) 或 (.25) 这样的输入
这里有一个解决方案-
TextFormField(
inputFormatters: [
WhitelistingTextInputFormatter(RegExp(r'^(\d+)?\.?\d{0,2}')),
],
)
可能这是一个更简单的解决方案
inputFormatters: [
FilteringTextInputFormatter.allow(RegExp(r'(^\d*\.?\d{0,2})'))
]
在 Flutter 版本 v1.20.0-1.0 之后。使用
TextFormField(
keyboardType: TextInputType.numberWithOptions(decimal: true),
inputFormatters: [
FilteringTextInputFormatter.allow(RegExp(r'^\d+\.?\d{0,2}')),
],
),
我认为这是最简单也是唯一适合我的方法:
inputFormatters: [ LengthLimitingTextInputFormatter(2), ]
飞镖 2.00+
TextFormField(
keyboardType: TextInputType.numberWithOptions(decimal: true),
inputFormatters: [
// Allow Decimal Number With Precision of 2 Only
FilteringTextInputFormatter.allow(RegExp(r'^\d*\.?\d{0,2}')),
],
它允许像 1.
、.89
、8.99
Dart SDK 版本:2.13.4(稳定) Flutter 2.2.3 • 通道稳定
我在 2021 年 7 月 25 日写了这个答案,提出了一个更简单的解决方案,只使用内置 TextField 的 inputFormatters
。
我试图向你们所有人保证,该字段不会接受长于 2 的浮点数(已接受:12.25 与未接受:65.536)。而且,它不会接受多个点,只接受一个点(接受:12.25 vs notAccepted:1.1.11, 1.11, .1.1, 1.1.1.1, whatever..)。
考虑到其他答案的不同之处在于,下面的代码不会以编程方式接受等于 0.1
的 .1
,这实际上更加用户友好。它很简单,对我们来说很好看。您只需将下面的代码复制并粘贴到 inputFormatters: []
.
如果你想同时接受0.1
和.1
(不仅仅是0.1
),你可以注释掉FilteringTextInputFormatter.allow(RegExp(r'^\d+\.?\d*'))
!
inputFormatters: [ FilteringTextInputFormatter.allow(RegExp(r'^(\d+)?\.?\d{0,2}')), FilteringTextInputFormatter.allow(RegExp(r'^\d+\.?\d*')), ]
当你想改变最大小数点时,你可以改变下面一行中的N
值:
inputFormatters: [ FilteringTextInputFormatter.allow(RegExp(r'^(\d+)?\.?\d{0,N}')), FilteringTextInputFormatter.allow(RegExp(r'^\d+\.?\d*')), ]
第一个例子展示了你想限制小数点为2的情况,而N值恰好控制了这个限制。您可以在自己的代码中尝试 [:
感谢所有其他答案,希望这个答案可以帮助未来的流浪者!祝你有美好的一天[:
对于 Flutter 中的 TextFeild 小数点前和小数点后长度验证 class.
import 'package:flutter/cupertino.dart';
import 'package:flutter/services.dart';
import 'dart:math' as math;
class DecimalTextInputFormatter extends TextInputFormatter {
DecimalTextInputFormatter({this.decimalRange,this.beforeDecimalRange})
: assert(decimalRange == null || decimalRange > 0 || beforeDecimalRange == null || beforeDecimalRange > 0 );
final int decimalRange;
final int beforeDecimalRange;
@override
TextEditingValue formatEditUpdate(
TextEditingValue oldValue, // unused.
TextEditingValue newValue,
) {
TextSelection newSelection = newValue.selection;
String truncated = newValue.text;
String value;
if(beforeDecimalRange != null){
value = newValue.text;
if(value.contains(".")){
if(value.split(".")[0].length > beforeDecimalRange){
truncated = oldValue.text;
newSelection = oldValue.selection;
}
}else{
if(value.length > beforeDecimalRange){
truncated = oldValue.text;
newSelection = oldValue.selection;
}
}
}
if (decimalRange != null) {
value = newValue.text;
if (value.contains(".") &&
value.substring(value.indexOf(".") + 1).length > decimalRange) {
truncated = oldValue.text;
newSelection = oldValue.selection;
} else if (value == ".") {
truncated = "0.";
newSelection = newValue.selection.copyWith(
baseOffset: math.min(truncated.length, truncated.length + 1),
extentOffset: math.min(truncated.length, truncated.length + 1),
);
}
return TextEditingValue(
text: truncated,
selection: newSelection,
composing: TextRange.empty,
);
}
return newValue;
}
}
在文本字段中, 前任。小数点前 9 位和小数点后 2 位允许以下代码。
inputFormatters: [ FilteringTextInputFormatter.allow(RegExp(r'^\d+\.?\d{0,2}')),
DecimalTextInputFormatter(decimalRange: 2, beforeDecimalRange: 9)
],
keyboardType: TextInputType.numberWithOptions(decimal: true),
这对我有用 (Feb/2022)
将文本限制为 2 个小数点并且只有 1 个“.” (句点)
0 将自动添加到号码的开头,如果用户手动删除“.”之前的数字
PS:对答案稍作编辑
TextFormField
TextFormField(
autofocus: false,
keyboardType: TextInputType.number,
controller: controller,
inputFormatters: [
DecimalTextInputFormatter(decimalRange: 2),
],
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please add amount.';
}
return null;
},
DecimalTextInputFormatter
import 'package:flutter/services.dart';
import 'dart:math' as math;
class DecimalTextInputFormatter extends TextInputFormatter {
DecimalTextInputFormatter({required this.decimalRange})
: assert(decimalRange > 0);
final int decimalRange;
@override
TextEditingValue formatEditUpdate(
TextEditingValue oldValue,
TextEditingValue newValue,
) {
TextSelection newSelection = newValue.selection;
String truncated = newValue.text;
String value = newValue.text;
if (value.contains(".") &&
value.substring(value.indexOf(".") + 1).length > decimalRange) {
truncated = oldValue.text;
newSelection = oldValue.selection;
} else if (value == ".") {
truncated = "0.";
newSelection = newValue.selection.copyWith(
baseOffset: math.min(truncated.length, truncated.length + 1),
extentOffset: math.min(truncated.length, truncated.length + 1),
);
} else if (value.contains(".")) {
String tempValue = value.substring(value.indexOf(".") + 1);
if (tempValue.contains(".")) {
truncated = oldValue.text;
newSelection = oldValue.selection;
}
if (value.indexOf(".") == 0) {
truncated = "0" + truncated;
newSelection = newValue.selection.copyWith(
baseOffset: math.min(truncated.length, truncated.length + 1),
extentOffset: math.min(truncated.length, truncated.length + 1),
);
}
}
if (value.contains(" ") || value.contains("-")) {
truncated = oldValue.text;
newSelection = oldValue.selection;
}
return TextEditingValue(
text: truncated,
selection: newSelection,
composing: TextRange.empty,
);
}
}