Flutter TextField 设置默认值、光标位置、限定输入类型

这篇博客介绍了如何在Flutter中创建一个自定义的`XNumberTextInputFormatter`类,用于限制用户输入的整数和小数长度,并确保输入值为有效的数字。通过这个类,开发者可以更好地控制文本输入字段的格式,例如在金融或计量应用中确保数据准确无误。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

TextField(
				//设置默认值,光标在文字最后
                controller: TextEditingController.fromValue(TextEditingValue(
                        text: _strRepairCloudInfo,
                        selection: TextSelection.fromPosition(TextPosition(
                            affinity: TextAffinity.downstream,
                            offset: _strRepairCloudInfo.length)))),
                maxLines: 2,
                autofocus: hintText == '今日工作内容' ? true : false,
                textInputAction: TextInputAction.next,
                //设置 输入内容,整数或者有效数字
                keyboardType: TextInputType.numberWithOptions(decimal: false),
                  inputFormatters: [
                    XNumberTextInputFormatter(
                        maxIntegerLength: _maxIntegerLength,
                        maxDecimalLength: 2,
                        isAllowDecimal: false),
                  ],
                //防止IOS,双击长按,异常。
                enableInteractiveSelection: false,
                decoration: InputDecoration(
                  contentPadding: EdgeInsets.zero,
                  isCollapsed: false,
                  hintText: '请输入',
                  hintStyle: TextStyle(fontSize: 13, color: Colors.grey),
                  border: InputBorder.none,
                ),
                onChanged: (value) {
               		
                },
              ),
import 'package:flutter/services.dart';

class XNumberTextInputFormatter extends TextInputFormatter {
  int _maxIntegerLength;
  int _maxDecimalLength;
  bool _isAllowDecimal;

  /// [maxIntegerLength]限定整数的最大位数,为null时不限
  /// [maxDecimalLength]限定小数点的最大位数,为null时不限
  /// [isAllowDecimal]是否可以为小数,默认是可以为小数,也就是可以输入小数点
  XNumberTextInputFormatter(
      {int maxIntegerLength, int maxDecimalLength, bool isAllowDecimal = true})
      : _maxIntegerLength = maxIntegerLength,
        _maxDecimalLength = maxDecimalLength,
        _isAllowDecimal = isAllowDecimal;

  @override
  TextEditingValue formatEditUpdate(
      TextEditingValue oldValue, TextEditingValue newValue) {
    String value = newValue.text?.trim(); //去掉前后空格
    int selectionIndex = newValue.selection.end;
    if (_isAllowDecimal) {
      if (value == '.') {
        value = '0.';
        selectionIndex++;
      } else if (value != '' && _isToDoubleError(value)) {
        //不是double输入数据
        return _oldTextEditingValue(oldValue);
      }
      //包含小数点
      if (value.contains('.')) {
        int pointIndex = value.indexOf('.');
        String beforePoint = value.substring(0, pointIndex);
//      print('$beforePoint');
        String afterPoint = value.substring(pointIndex + 1, value.length);
//      print('$afterPoint');
        //小数点前面没内容补0
        if (beforePoint.length == 0) {
          value = '0.${afterPoint ?? ''}';
          selectionIndex++;
        } else {
          //限定整数位数
          if (null != _maxIntegerLength) {
            if (beforePoint.length > _maxIntegerLength) {
              return _oldTextEditingValue(oldValue);
            }
          }
        }
        //限定小数点位数
        if (null != _maxDecimalLength) {
          if (afterPoint.length > _maxDecimalLength) {
            return _oldTextEditingValue(oldValue);
          }
        }
      } else {
        //限定整数位数
        if (null != _maxIntegerLength) {
          if (value.length > _maxIntegerLength) {
            return _oldTextEditingValue(oldValue);
          }
        }
      }
    } else {
      if (value.contains('.') ||
          (value != '' && _isToDoubleError(value)) ||
          (null!=_maxIntegerLength&&value.length > _maxIntegerLength)) {
        return _oldTextEditingValue(oldValue);
      }
    }

    return TextEditingValue(
      text: value,
      selection: TextSelection.collapsed(offset: selectionIndex),
    );
  }

  ///返回旧的输入内容
  TextEditingValue _oldTextEditingValue(TextEditingValue oldValue) {
    return TextEditingValue(
      text: oldValue.text,
      selection: TextSelection.collapsed(offset: oldValue.selection.end),
    );
  }

  ///输入内容不能解析成double
  bool _isToDoubleError(String value) {
    try {
      double.parse(value);
    } catch (e) {
      return true;
    }
    return false;
  }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值