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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 03:45:03