You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter中如何限制连续两个点输入?基于TextInputFormField实现规范小数输入

Solution: Enforce Valid Decimal Input & Block Consecutive Dots in TextInputFormField

Got it, let's fix this input issue for you. You want to stop users from entering things like 1.. and enforce clean decimal formats like 1.23 using a formatter with TextInputFormField—here's a straightforward, customizable approach:

Step 1: Build a Custom Decimal Input Formatter

Instead of relying on a generic formatter, let's create one that explicitly blocks consecutive dots and enforces your desired decimal rules. This gives you full control over the input behavior:

class ValidDecimalFormatter extends TextInputFormatter {
  final int maxDecimalPlaces;

  ValidDecimalFormatter({this.maxDecimalPlaces = 2});

  @override
  TextEditingValue formatEditUpdate(
      TextEditingValue oldValue, TextEditingValue newValue) {
    String inputText = newValue.text;

    // Handle empty input
    if (inputText.isEmpty) return newValue;

    // Block multiple decimal points (e.g., turn "1..2" into "1.2")
    if (inputText.contains('.')) {
      final parts = inputText.split('.');
      if (parts.length > 2) {
        inputText = '${parts[0]}.${parts.sublist(1).join()}';
      }
      // Limit decimal places to your desired count
      if (parts.length == 2 && parts[1].length > maxDecimalPlaces) {
        inputText = '${parts[0]}.${parts[1].substring(0, maxDecimalPlaces)}';
      }
    }

    // Prevent invalid leading zeros (e.g., "0012.34" becomes "12.34")
    if (inputText.startsWith('0') && inputText.length > 1 && !inputText.startsWith('0.')) {
      inputText = inputText.substring(1);
    }

    return TextEditingValue(
      text: inputText,
      selection: TextSelection.collapsed(offset: inputText.length),
    );
  }
}

Step 2: Integrate the Formatter into Your TextInputFormField

Now plug this formatter into your field, along with basic validation to ensure the final input is a valid number:

TextInputFormField(
  keyboardType: TextInputType.numberWithOptions(decimal: true),
  inputFormatters: [
    // Regex to allow only digits, one decimal point, and up to 2 decimals
    FilteringTextInputFormatter.allow(RegExp(r'^\d+\.?\d{0,2}')),
    ValidDecimalFormatter(maxDecimalPlaces: 2), // Our custom formatter
  ],
  decoration: InputDecoration(
    labelText: 'Enter Decimal Number',
    border: OutlineInputBorder(),
  ),
  validator: (value) {
    if (value == null || value.isEmpty) {
      return 'Please enter a number';
    }
    if (double.tryParse(value) == null) {
      return 'Enter a valid decimal number (e.g., 1.23)';
    }
    return null;
  },
)

Key Features Breakdown

  • Blocks consecutive dots: Automatically cleans up inputs like 1..5 to 1.5 as the user types.
  • Adjustable decimal limits: Change maxDecimalPlaces to allow more/less decimal digits (e.g., 3 for 1.234).
  • Clean leading zeros: Stops messy inputs like 000.45 from being entered.

Alternative: Using a Pre-built Decimal Formatter

If you prefer using an existing package formatter (like from flutter_form_builder), you can combine it with our custom logic to cover the consecutive dot edge case:

// Add flutter_form_builder to your pubspec.yaml first
TextInputFormField(
  keyboardType: TextInputType.numberWithOptions(decimal: true),
  inputFormatters: [
    DecimalInputFormatter(decimalRange: 2, enabledNegative: false),
    ValidDecimalFormatter(maxDecimalPlaces: 2), // Adds the consecutive dot block
  ],
  // Rest of your field properties...
)

内容的提问来源于stack exchange,提问作者Jaya kumar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 09:02:39