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

Flutter点击按钮或单选框时文本框自动清空问题求助

Flutter文本框点击按钮/单选框后自动清空的解决方案

问题根源

你把所有TextEditingController实例都定义在build方法内部了:

Widget build(BuildContext context1) {
  TextEditingController getUsername = TextEditingController();
  // 其他控制器...
}

每次调用setState(单选框切换、按钮点击都会触发),Flutter会重新执行build方法,重新创建所有控制器。新的控制器没有保存之前输入的文本,所以文本框看起来被清空了。

修复方案

将TextEditingController移到_ProfileScreenState类的成员变量位置,让它们在组件生命周期内保持实例不变:

修改后的完整代码

import 'package:flutter/material.dart';
import 'NavDrawer.dart';

class proFile extends StatelessWidget {
  static const String routeName = '/profile';

  const proFile({super.key});

  @override
  build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: const Text("Profile"),
        ),
        drawer: const NavDrawer(),
        body: ProfileScreen());
  }
}

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

  @override
  _ProfileScreenState createState() {
    return _ProfileScreenState();
  }
}

enum Gender { male, female }
String getGender="";
class _ProfileScreenState extends State<ProfileScreen> {
  Gender? _gender = Gender.male;
  
  // 控制器定义为类成员变量
  late TextEditingController getUsername;
  late TextEditingController getFName;
  late TextEditingController getLName;
  late TextEditingController getPass;
  late TextEditingController getCPass;
  late TextEditingController getEmail;
  late TextEditingController var5;

  @override
  void initState() {
    super.initState();
    // 初始化控制器(仅组件创建时执行一次)
    getUsername = TextEditingController();
    getFName = TextEditingController();
    getLName = TextEditingController();
    getPass = TextEditingController();
    getCPass = TextEditingController();
    getEmail = TextEditingController();
    var5 = TextEditingController();
  }

  @override
  void dispose() {
    // 释放控制器资源,避免内存泄漏
    getUsername.dispose();
    getFName.dispose();
    getLName.dispose();
    getPass.dispose();
    getCPass.dispose();
    getEmail.dispose();
    var5.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context1) {
    return SingleChildScrollView(
      child: Column(
        children: <Widget>[
          Row(
            children: <Widget>[
              Container(
                margin: EdgeInsets.all(20),
                child: Text("Enter Your Profile",
                    style: TextStyle(fontSize: 40, color: Colors.black)),
              ),
            ],
          ),
          // row2
          Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Container(
                height: 50,
                width: 500,
                margin: EdgeInsets.all(10),
                child: TextField(
                    keyboardType: TextInputType.text,
                    controller: getUsername,
                    decoration: InputDecoration(
                        border: const OutlineInputBorder(
                            borderSide:
                                const BorderSide(color: Colors.lightGreen)),
                        labelText: "Enter Your UserName")),
              )
            ],
          ),
          // row3
          Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Container(
                height: 50,
                width: 500,
                margin: EdgeInsets.all(10),
                child: TextField(
                    controller: getFName,
                    keyboardType: TextInputType.text,
                    decoration: InputDecoration(
                        border: const OutlineInputBorder(
                            borderSide:
                                const BorderSide(color: Colors.lightGreen)),
                        labelText: "Enter Your First Name")),
              )
            ],
          ),
          // row4
          Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Container(
                height: 50,
                width: 500,
                margin: EdgeInsets.all(10),
                child: TextField(
                    controller: getLName,
                    keyboardType: TextInputType.text,
                    decoration: InputDecoration(
                        border: const OutlineInputBorder(
                            borderSide:
                                const BorderSide(color: Colors.lightGreen)),
                        labelText: "Enter Your Last Name")),
              )
            ],
          ),
          Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Container(
                height: 50,
                width: 500,
                margin: EdgeInsets.all(10),
                child: TextField(
                    controller: getPass,
                    keyboardType: TextInputType.text,
                    decoration: InputDecoration(
                        border: const OutlineInputBorder(
                            borderSide:
                                const BorderSide(color: Colors.lightGreen)),
                        labelText: "Enter Your Password")),
              )
            ],
          ),
          Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Container(
                height: 50,
                width: 500,
                margin: EdgeInsets.all(10),
                child: TextField(
                    controller: getCPass,
                    keyboardType: TextInputType.text,
                    decoration: InputDecoration(
                        border: const OutlineInputBorder(),
                        labelText: "Confirm Your Password")),
              )
            ],
          ),
          Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Container(
                height: 50,
                width: 500,
                margin: EdgeInsets.all(10),
                child: TextField(
                    controller: getEmail,
                    keyboardType: TextInputType.text,
                    decoration: InputDecoration(
                        border: const OutlineInputBorder(),
                        labelText: "Enter Your Email")),
              )
            ],
          ),
          Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Container(
                height: 50,
                width: 400,
                child:ListTile(
                  title: const Text('Male'),
                  leading: Radio(
                    value: Gender.male,
                    groupValue: _gender,
                    onChanged: (Gender? value) {
                      setState(() {
                        _gender = value;
                      });
                    },
                  ),
                ),
              ),
              Container(
                height: 50,
                width: 400,
                child:ListTile(
                  title: const Text('Female'),
                  leading: Radio(
                    value: Gender.female,
                    groupValue: _gender,
                    onChanged: (Gender? value) {
                      setState(() {
                        _gender = value;
                      });
                    },
                  ),
                ),
              )
            ],
          ),
          Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Container(
                height: 100,
                width: 500,
                margin: EdgeInsets.all(1),
                child: TextField(
                    maxLines: 8,
                    controller: var5,
                    keyboardType: TextInputType.text,
                    decoration: InputDecoration(
                        border: const UnderlineInputBorder(borderSide:
                        const BorderSide(color: Colors.lightGreen)),
                        labelText: "")),
              )
            ],
          ),
          Row(
              children: <Widget>[
                const SizedBox(height: 55.0, width: 20.0),
                SizedBox(
                  width: 250.0,
                  height: 70,
                  child: ElevatedButton(
                    child: const Text("Submit!"),
                    style: ElevatedButton.styleFrom(
                        backgroundColor: Colors.green,
                        padding: EdgeInsets.all(20),
                        shape: RoundedRectangleBorder(
                            borderRadius: BorderRadius.circular(20))),
                    onPressed: () {
                      setState(() {
                        String name = getUsername.text;
                        String fname = getFName.text;
                        String lname = getLName.text;
                        String pass = getPass.text;
                        String cpass = getCPass.text;
                        String email = getEmail.text;

                        var5.text="Inputted Result:\nName=$name\nFirst Name=$fname\nLast Name=$lname\nEmail=$email";
                      });
                    },
                  ),
                ),
              ]),
        ],
      ),
    );
  }
}

关键改动说明

  1. 将所有TextEditingController从build方法内移到_ProfileScreenState类的成员变量区域,用late关键字延迟初始化
  2. 在initState方法中初始化控制器(仅组件创建时执行一次)
  3. 在dispose方法中释放控制器资源,避免内存泄漏
  4. build方法内直接使用类成员变量的控制器,不再重新创建

这样修改后,每次setState触发重建时,控制器实例会保持不变,文本框的输入内容就不会丢失了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 23:55:32