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
相关产品推荐
相关产品推荐

