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

Flutter点击ElevatedButton光标定位TextField报错求助

问题修复与功能实现

错误原因

点击Check In/Check Out按钮时,代码错误地将车牌号输入框的内容尝试解析为整数(int.parse(textController.text)),但车牌号通常包含字母和数字,空输入也会触发解析失败,因此抛出FormatException。同时原代码未实现点击按钮聚焦指定输入框的功能。

修复与实现步骤

  • 新增FocusNode控制输入框聚焦,点击按钮时触发光标自动定位
  • 分离数字输入与车牌号输入的逻辑,避免解析错误
  • 添加异常捕获处理数字解析场景,防止崩溃
  • 优化代码结构,提升可读性

修复后的完整代码

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(home: Home());
  }
}

class Home extends StatefulWidget {
  @override
  State<Home> createState() => _HomeState();
}

class _HomeState extends State<Home> {
  final GlobalKey _parentKey = GlobalKey();
  int countItems = 0;
  late TextEditingController vehicleNumController;
  late TextEditingController countController;
  String? vehicle;
  late FocusNode vehicleFocusNode;

  @override
  void initState() {
    super.initState();
    vehicleNumController = TextEditingController();
    countController = TextEditingController();
    vehicleFocusNode = FocusNode();
  }

  @override
  void dispose() {
    vehicleNumController.dispose();
    countController.dispose();
    vehicleFocusNode.dispose();
    super.dispose();
  }

  void handleButtonTap() {
    // 安全解析车辆数量,避免格式错误
    try {
      if (countController.text.isNotEmpty) {
        setState(() {
          countItems = int.parse(countController.text);
        });
      }
    } catch (e) {
      setState(() {
        countItems = 0;
      });
    }
    // 聚焦到车牌号输入框
    vehicleFocusNode.requestFocus();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("GL-Complex"),
        backgroundColor: const Color.fromARGB(255, 106, 19, 19),
      ),
      body: SingleChildScrollView(
        child: Container(
          padding: const EdgeInsets.all(36),
          child: Column(
            children: [
              const Text(
                "GL-Parking(Vehicles)",
                style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
              ),
              const Divider(),
              RadioListTile(
                title: const Text("Bike"),
                value: "bike",
                groupValue: vehicle,
                onChanged: (value) {
                  setState(() {
                    vehicle = value.toString();
                  });
                },
              ),
              RadioListTile(
                title: const Text("Car"),
                value: "car",
                groupValue: vehicle,
                onChanged: (value) {
                  setState(() {
                    vehicle = value.toString();
                  });
                },
              ),
              const SizedBox(height: 10),
              // 单独的车辆数量输入框
              Padding(
                padding: const EdgeInsets.only(left: 20, right: 20.0),
                child: TextField(
                  controller: countController,
                  keyboardType: TextInputType.number,
                  decoration: const InputDecoration(
                    labelText: 'Number of Vehicles'
                  ),
                ),
              ),
              const SizedBox(height: 10),
              Padding(
                padding: const EdgeInsets.all(24),
                child: Column(children: <Widget>[
                  ElevatedButton(
                    onPressed: handleButtonTap,
                    child: const Text("Check In"),
                    style: ElevatedButton.styleFrom(
                      backgroundColor: const Color.fromARGB(255, 106, 19, 19),
                      minimumSize: const Size.fromHeight(50),
                    ),
                  ),
                  const SizedBox(height: 10),
                  ElevatedButton(
                    onPressed: handleButtonTap,
                    child: const Text("Check Out"),
                    style: ElevatedButton.styleFrom(
                      backgroundColor: const Color.fromARGB(255, 106, 19, 19),
                      minimumSize: const Size.fromHeight(50),
                    ),
                  ),
                ]),
              ),
              const SizedBox(height: 10),
              // 绑定焦点控制器的车牌号输入框
              Padding(
                padding: const EdgeInsets.only(left: 20, right: 20.0),
                child: TextField(
                  controller: vehicleNumController,
                  focusNode: vehicleFocusNode,
                  decoration: const InputDecoration(
                    labelText: 'Vehicle Number'
                  ),
                ),
              ),
              const SizedBox(height: 10),
              (countItems > 0)
                  ? Flexible(
                      child: ListView.builder(
                        shrinkWrap: true,
                        itemCount: countItems,
                        itemBuilder: (BuildContext context, int index) {
                          return TextField(
                            style: const TextStyle(color: Colors.white),
                            cursorColor: Colors.white,
                            textAlign: TextAlign.center,
                            decoration: InputDecoration(
                              hintText: "Enter Vehicle Number ${index + 1}",
                              hintStyle: TextStyle(color: Colors.grey[400]),
                            ),
                          );
                        },
                      ),
                    )
                  : const SizedBox(),
              Container(
                color: Colors.grey[200],
                padding: const EdgeInsets.all(24),
                child: Row(children: [
                  const Text(
                    "Print:",
                    style: TextStyle(fontWeight: FontWeight.bold),
                  ),
                  const SizedBox(width: 80),
                  Expanded(
                    child: TextButton.icon(
                      onPressed: () {},
                      icon: const Icon(Icons.print),
                      label: const Text('Save&Print'),
                      style: TextButton.styleFrom(
                        foregroundColor: Colors.white, backgroundColor: Colors.green,
                      ),
                    ),
                  ),
                ]),
              )
            ],
          ),
        ),
      ),
    );
  }
}

关键修改说明

  • 焦点控制:通过vehicleFocusNode实现点击按钮后自动聚焦到车牌号输入框
  • 安全解析:对数字解析添加异常捕获,避免空输入或非数字内容导致崩溃
  • 逻辑分离:将车辆数量输入与车牌号输入拆分,解决原代码的逻辑混淆问题
  • 布局优化:为ListView添加shrinkWrap: true,解决嵌套滚动组件的高度适配问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 11:20:38