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

Flutter中无法创建仅含小数点与负号的数字键盘怎么办?

如何在Flutter iOS端实现仅含数字、小数点、负号的数字键盘

你当前使用TextInputType.numberWithOptions(signed: true, decimal: true)在iOS模拟器中唤起的是带有额外标点的键盘,要实现目标样式的键盘,可通过以下两种方式解决:

方法1:过滤输入内容(快速满足功能需求)

保持现有键盘类型,通过输入格式化器过滤掉非允许的字符,确保用户只能输入数字、负号和小数点:

TextField(
  controller: amountController,
  autofocus: true,
  keyboardType: TextInputType.numberWithOptions(
    signed: true,
    decimal: true,
  ),
  textInputAction: TextInputAction.next,
  inputFormatters: [
    // 正则表达式允许:开头可选负号、任意数字、最多一个小数点、小数点后任意数字
    FilteringTextInputFormatter.allow(RegExp(r'^-?\d*\.?\d*')),
  ],
  decoration: const InputDecoration(
    label: Text('Amount'),
  ),
  onChanged: (value) {setState(() {});},
)

这种方式无需修改键盘样式,即使键盘上有其他标点,输入后会被自动过滤,最终输入内容完全符合要求。

方法2:自定义数字键盘(完全匹配目标样式)

如果需要严格匹配目标键盘的视觉样式,可自定义键盘组件,替换系统键盘:

步骤1:创建自定义键盘组件

class CustomNumberKeyboard extends StatelessWidget {
  final TextEditingController controller;
  final VoidCallback onDone;

  const CustomNumberKeyboard({
    super.key,
    required this.controller,
    required this.onDone,
  });

  void _handleKeyPress(String key) {
    switch(key) {
      case 'backspace':
        if (controller.text.isNotEmpty) {
          controller.text = controller.text.substring(0, controller.text.length - 1);
        }
        break;
      case '-':
        controller.text = controller.text.startsWith('-') 
            ? controller.text.substring(1) 
            : '-' + controller.text;
        break;
      case '.':
        if (!controller.text.contains('.')) {
          controller.text += '.';
        }
        break;
      case 'done':
        onDone();
        break;
      default:
        controller.text += key;
    }
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.grey[200],
      child: GridView.count(
        shrinkWrap: true,
        crossAxisCount: 3,
        childAspectRatio: 2,
        padding: const EdgeInsets.all(8),
        children: [
          _buildKey('1'),
          _buildKey('2'),
          _buildKey('3'),
          _buildKey('4'),
          _buildKey('5'),
          _buildKey('6'),
          _buildKey('7'),
          _buildKey('8'),
          _buildKey('9'),
          _buildKey('-'),
          _buildKey('0'),
          _buildKey('.'),
          _buildKey('backspace', icon: Icons.backspace),
          const SizedBox(),
          _buildKey('done'),
        ],
      ),
    );
  }

  Widget _buildKey(String key, {IconData? icon}) {
    return GestureDetector(
      onTap: () => _handleKeyPress(key),
      child: Container(
        margin: const EdgeInsets.all(4),
        decoration: BoxDecoration(
          color: Colors.white,
          borderRadius: BorderRadius.circular(8),
        ),
        child: Center(
          child: icon != null
              ? Icon(icon, size: 24)
              : Text(
                  key,
                  style: const TextStyle(fontSize: 20, fontWeight: FontWeight.w500),
                ),
        ),
      ),
    );
  }
}

步骤2:在页面中使用自定义键盘

class AmountInputPage extends StatefulWidget {
  const AmountInputPage({super.key});

  @override
  State<AmountInputPage> createState() => _AmountInputPageState();
}

class _AmountInputPageState extends State<AmountInputPage> {
  final TextEditingController amountController = TextEditingController();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('金额输入')),
      body: Column(
        children: [
          TextField(
            controller: amountController,
            autofocus: true,
            keyboardType: TextInputType.none, // 隐藏系统键盘
            decoration: const InputDecoration(
              label: Text('Amount'),
              border: OutlineInputBorder(),
              contentPadding: EdgeInsets.symmetric(horizontal: 16, vertical: 12),
            ),
          ),
          Expanded(child: Container()), // 占位,把键盘推到底部
          CustomNumberKeyboard(
            controller: amountController,
            onDone: () => FocusScope.of(context).unfocus(),
          ),
        ],
      ),
    );
  }
}

这种方式可以完全自定义键盘的布局和样式,实现与目标图一致的效果,且在iOS和Android端表现统一。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 04:35:57