Flutter实现点击ElevatedButton将按钮数字传入选中TextField的开发问题
卡牌游戏积分计算器功能实现
实现要点
- 改造原StatelessWidget为StatefulWidget,管理输入框控制器与聚焦状态
- 为两个输入框分别绑定
TextEditingController和FocusNode,自动识别当前选中的输入框 - 数字按钮点击时将对应数字追加到当前聚焦输入框的内容末尾,同时保留手动输入能力
- 同步实现逐位删除、清空输入的配套功能
完整代码
import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; class GameScreen extends StatefulWidget { const GameScreen({Key? key}) : super(key: key); @override State<GameScreen> createState() => _GameScreenState(); } class _GameScreenState extends State<GameScreen> { final TextEditingController _miController = TextEditingController(); final TextEditingController _viController = TextEditingController(); final FocusNode _miFocus = FocusNode(); final FocusNode _viFocus = FocusNode(); // 输入数字逻辑 void _inputNumber(String num) { if (_miFocus.hasFocus) { _miController.text += num; _miController.selection = TextSelection.fromPosition( TextPosition(offset: _miController.text.length)); } else if (_viFocus.hasFocus) { _viController.text += num; _viController.selection = TextSelection.fromPosition( TextPosition(offset: _viController.text.length)); } } // 删除一位逻辑 void _deleteOne() { if (_miFocus.hasFocus && _miController.text.isNotEmpty) { _miController.text = _miController.text.substring(0, _miController.text.length - 1); _miController.selection = TextSelection.fromPosition( TextPosition(offset: _miController.text.length)); } else if (_viFocus.hasFocus && _viController.text.isNotEmpty) { _viController.text = _viController.text.substring(0, _viController.text.length - 1); _viController.selection = TextSelection.fromPosition( TextPosition(offset: _viController.text.length)); } } // 清空当前输入逻辑 void _clear() { if (_miFocus.hasFocus) { _miController.clear(); } else if (_viFocus.hasFocus) { _viController.clear(); } } @override void dispose() { _miController.dispose(); _viController.dispose(); _miFocus.dispose(); _viFocus.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( body: SafeArea( child: Column(children: <Widget>[ const Spacer(), SizedBox( height: 100, child: Row(children: const [ Expanded( child: Center( child: Text( "MI", style: TextStyle(fontSize: 50), ), )), Expanded( child: Center( child: Text( "VI", style: TextStyle(fontSize: 50), ), )), ])), const Spacer(), Row( children: [ Expanded( child: Padding( padding: const EdgeInsets.symmetric(horizontal: 16), child: TextField( controller: _miController, focusNode: _miFocus, keyboardType: TextInputType.number, decoration: const InputDecoration( border: OutlineInputBorder(), contentPadding: EdgeInsets.all(12), ), textAlign: TextAlign.center, style: const TextStyle(fontSize: 30), ), ), ), Expanded( child: Padding( padding: const EdgeInsets.symmetric(horizontal: 16), child: TextField( controller: _viController, focusNode: _viFocus, keyboardType: TextInputType.number, decoration: const InputDecoration( border: OutlineInputBorder(), contentPadding: EdgeInsets.all(12), ), textAlign: TextAlign.center, style: const TextStyle(fontSize: 30), ), ), ), ], ), const Spacer(), Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ ElevatedButton( onPressed: () {}, style: ElevatedButton.styleFrom( padding: const EdgeInsets.only( top: 20, bottom: 20, right: 20, left: 20)), child: const Text('CONTACTS', style: TextStyle( color: Colors.white, fontSize: 30, fontWeight: FontWeight.bold))), ElevatedButton( onPressed: () {}, style: ElevatedButton.styleFrom( padding: const EdgeInsets.only( top: 20, bottom: 20, right: 50, left: 50)), child: const Text('POINTS', style: TextStyle( color: Colors.white, fontSize: 30, fontWeight: FontWeight.bold))), ], ), const Spacer(), Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ ElevatedButton( onPressed: () => _inputNumber('7'), style: ElevatedButton.styleFrom( padding: const EdgeInsets.only( top: 20, bottom: 20, right: 50, left: 50)), child: const Text('7', style: TextStyle(color: Colors.white, fontSize: 30))), ElevatedButton( onPressed: () => _inputNumber('8'), style: ElevatedButton.styleFrom( padding: const EdgeInsets.only( top: 20, bottom: 20, right: 50, left: 50)), child: const Text('8', style: TextStyle(color: Colors.white, fontSize: 30))), ElevatedButton( onPressed: () => _inputNumber('9'), style: ElevatedButton.styleFrom( padding: const EdgeInsets.only( top: 20, bottom: 20, right: 50, left: 50)), child: const Text('9', style: TextStyle(color: Colors.white, fontSize: 30))), ], ), const Spacer(), Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ ElevatedButton( onPressed: () => _inputNumber('4'), style: ElevatedButton.styleFrom( padding: const EdgeInsets.only( top: 20, bottom: 20, right: 50, left: 50)), child: const Text('4', style: TextStyle(color: Colors.white, fontSize: 30))), ElevatedButton( onPressed: () => _inputNumber('5'), style: ElevatedButton.styleFrom( padding: const EdgeInsets.only( top: 20, bottom: 20, right: 50, left: 50)), child: const Text('5', style: TextStyle(color: Colors.white, fontSize: 30))), ElevatedButton( onPressed: () => _inputNumber('6'), style: ElevatedButton.styleFrom( padding: const EdgeInsets.only( top: 20, bottom: 20, right: 50, left: 50)), child: const Text('6', style: TextStyle(color: Colors.white, fontSize: 30))), ], ), const Spacer(), Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ ElevatedButton( onPressed: () => _inputNumber('1'), style: ElevatedButton.styleFrom( padding: const EdgeInsets.only( top: 20, bottom: 20, right: 50, left: 50)), child: const Text('1', style: TextStyle(color: Colors.white, fontSize: 30))), ElevatedButton( onPressed: () => _inputNumber('2'), style: ElevatedButton.styleFrom( padding: const EdgeInsets.only( top: 20, bottom: 20, right: 50, left: 50)), child: const Text('2', style: TextStyle(color: Colors.white, fontSize: 30))), ElevatedButton( onPressed: () => _inputNumber('3'), style: ElevatedButton.styleFrom( padding: const EdgeInsets.only( top: 20, bottom: 20, right: 50, left: 50)), child: const Text('3', style: TextStyle(color: Colors.white, fontSize: 30))), ], ), const Spacer(), Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ ElevatedButton( onPressed: _deleteOne, style: ElevatedButton.styleFrom( padding: const EdgeInsets.only( top: 20, bottom: 20, right: 40, left: 40)), child: const Text('Del 1', style: TextStyle(color: Colors.white, fontSize: 24))), ElevatedButton( onPressed: () => _inputNumber('0'), style: ElevatedButton.styleFrom( padding: const EdgeInsets.only( top: 20, bottom: 20, right: 50, left: 50)), child: const Text('0', style: TextStyle(color: Colors.white, fontSize: 30))), ElevatedButton( onPressed: _clear, style: ElevatedButton.styleFrom( padding: const EdgeInsets.only( top: 20, bottom: 20, right: 40, left: 40)), child: const Text('Clear', style: TextStyle(color: Colors.white, fontSize: 24))), ], ), const Spacer(), ElevatedButton( onPressed: () {}, style: ElevatedButton.styleFrom( padding: const EdgeInsets.only( top: 20, bottom: 20, right: 70, left: 70)), child: const Text('SAVE GAME', style: TextStyle( color: Colors.white, fontSize: 40, fontWeight: FontWeight.bold))), const Spacer(), ]))); } }
内容的提问来源于stack exchange,提问作者Croatia Games
相关产品推荐
相关产品推荐

