只允许在颤振文本字段中输入数字颤振

时间:2021-03-04 15:02:58

标签: flutter textfield

我已经创建了我的文本字段,它应该只允许输入数字以进行一些计算,我稍后将在输入值后执行此操作。它几乎工作正常,但有一个问题。

这是该字段的代码

var numberInputFormatters = [new FilteringTextInputFormatter.allow(RegExp("[0-9]")),];


  String _tip='2';
  Widget _buildOtherTipInput() {
    return TextFormField(
      style: inputTextStyle,
      inputFormatters: numberInputFormatters,
      keyboardType: TextInputType.number,
      decoration: formInputDecoration.copyWith(
          prefix: Text('\$'),
          labelText: 'Enter Custom Tip Amount ',
          hintStyle: TextStyle(fontWeight: FontWeight.w600)
      ),
      onChanged: (val){
       setState(() {
         val!=null?_tip=val:_tip='0';
       });
      },

    );
  }

所以当你输入一个数字然后尝试输入一个非数字字符时,它不会接受输入但是如果我尝试输入一个不是数字的字符作为第一个,我会抛出这个错误

Invalid double

我确实知道它来自下面的这段代码,它将字符串输入转换为双精度值。我不明白的是为什么它首先收到无效的双精度值,但我在文本字段中为无效(非数字)输入设置了阻止程序。

  String getTotal(){
    String theTip=_tip??'0';
     double  newTip = double.parse(theTip).truncateToDouble();
    return newTip.toStringAsFixed(2);
  }

2 个答案:

答案 0 :(得分:3)

快速回答

您的问题是 val 永远不会是 null

输入错误字符后,val''。您应该检查它是否为空:

onChanged: (val){
  setState(() {
    val.isNotEmpty ? _tip=val : _tip='0';
  });
},

更长的答案

enter image description here

与其定义自己的 numberInputFormatters,不如使用 FilteringTextInputFormatter.digitsOnly

此外,您的 _tip 不是 String,您可以将其值存储为 int

您的 onChanged 回调变为:

onChanged: (val) => setState(() => _tip = int.tryParse(val) ?? 0),

完整源代码:

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

void main() {
  runApp(
    MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Flutter Demo',
      home: MyWidget(price: 9.99),
    ),
  );
}

class MyWidget extends StatefulWidget {
  final double price;

  const MyWidget({Key key, this.price}) : super(key: key);

  @override
  _MyWidgetState createState() => _MyWidgetState();
}

class _MyWidgetState extends State<MyWidget> {
  int _tip = 2;

  String get _total => (widget.price + _tip).toStringAsFixed(2);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        alignment: Alignment.center,
        padding: EdgeInsets.all(16.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text('Do you want to tip the waiter?'),
            const SizedBox(height: 16.0),
            TextFormField(
              initialValue: _tip.toString(),
              inputFormatters: [FilteringTextInputFormatter.digitsOnly],
              keyboardType: TextInputType.number,
              decoration: InputDecoration(
                  prefix: Text('\$'),
                  labelText: 'Enter Custom Tip Amount ',
                  hintStyle: TextStyle(fontWeight: FontWeight.w600)),
              onChanged: (val) => setState(() => _tip = int.tryParse(val) ?? 0),
            ),
            const SizedBox(height: 16.0),
            Text('TOTAL: $_total'),
          ],
        ),
      ),
    );
  }
}

答案 1 :(得分:0)

考虑使用字符串验证器,它易于使用

https://pub.dev/packages/string_validator