颤振输入中仅允许使用两个十进制数字?

时间:2019-01-31 06:58:27

标签: dart flutter flutter-layout

在颤振输入中,我只希望小数点后两位。用户不能在小数点后添加两位以上。

13 个答案:

答案 0 :(得分:14)

这是对我有用的解决方案

TextFormField(
    inputFormatters: [
        WhitelistingTextInputFormatter(RegExp(r'^\d+\.?\d{0,2}')),
    ],
)

如果您想允许输入(.21)或(.25)

这是一个解决方案-

TextFormField(
    inputFormatters: [
        WhitelistingTextInputFormatter(RegExp(r'^(\d+)?\.?\d{0,2}')),
    ],
)

答案 1 :(得分:7)

您在这里! 希望对您有所帮助:)

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;
  }
}

答案 2 :(得分:2)

也许对您来说有点晚,但我也有所改善:

  1. 仅允许1个.
  2. 允许否定
  3. 在开始处加上负号

希望它会有所帮助;)

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);
  }
}

(不要忘记导入上一个类)

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),
      ],
    );
  }
}

答案 3 :(得分:2)

Flutter版本v1.20.0-1.0之后的

。使用

TextFormField(
  keyboardType: TextInputType.numberWithOptions(decimal: true),
  inputFormatters: [
    FilteringTextInputFormatter.allow(RegExp(r'^\d+\.?\d{0,2}')),
  ],
),

答案 4 :(得分:1)

使用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;
  }
}

答案 5 :(得分:1)

也许这是一个更简单的解决方案

inputFormatters: [
            FilteringTextInputFormatter.allow(RegExp(r'(^\d*\.?\d{0,2})'))
          ]

答案 6 :(得分:1)

对于 Dart 2.00+

MATCH (users:User {role: "USER", hasCompletedRegistration: true})
RETURN users

它允许小数,如 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

答案 7 :(得分:0)

我扩展了功能...希望您能发现它有用。告诉我是否可以进一步改善。

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;
}
}

答案 8 :(得分:0)

@AjayKumar的答案允许将文本输入限制为必需的小数位。但是我的要求是避免键盘上除了数字和点之外的另一个字符。因此,我更新了@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;

} }

答案 9 :(得分:0)

并避免不必要的零...请调试此代码。

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;
  }
}

答案 10 :(得分:0)

我认为这是对我来说最简单也是唯一的方法:

inputFormatters: [ LengthLimitingTextInputFormatter(2), ]

答案 11 :(得分:0)

Dart SDK 版本:2.13.4(稳定版) Flutter 2.2.3 • 通道稳定

我是在 2021 年 7 月 25 日写下这个答案的,建议使用更简单的解决方案,仅使用内置 TextField 的 inputFormatters

我正在努力确保你们所有人,该字段不会接受超过 2 的浮点数(接受:12.25 vs notAccepted:65.536)。而且,它不接受多个点,只接受一个点(接受:12.25 vs notAccepted:1.1.11、1.11、.1.1、1.1.1.1,无论如何......)。

考虑到其他答案的不同之处在于,下面的代码不会以编程方式接受 .1 等于 0.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*')), ]

感谢所有其他答案,希望这个答案可以帮助未来的流浪者!度过美好的一天[:

答案 12 :(得分:0)

对于TextFeild in Flutter,带有小数点前和小数点后长度验证类。

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;
  }
}    

在 TextFeild 中, 前任。小数点前 9 位数字和小数点后 2 位数字允许代码如下。

inputFormatters: [ FilteringTextInputFormatter.allow(RegExp(r'^\d+\.?\d{0,2}')),
                   DecimalTextInputFormatter(decimalRange: 2, beforeDecimalRange: 9)
                 ],
keyboardType: TextInputType.numberWithOptions(decimal: true),