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

Flutter如何获取TextField输入值?TextEditingController跨组件调用报错怎么解决

你遇到的两处报错分别来自两个典型的Flutter作用域问题:

  1. 自定义输入组件是独立的类,无法直接访问父组件State中定义的控制器
  2. loginAct方法不在_LoginState类的作用域内,同时你提交数据时直接传入了控制器实例而非输入的文本值

步骤1:修改自定义输入组件,增加控制器入参

给TextInputField和PasswordInput都新增必填的TextEditingController构造参数,示例如下:

class TextInputField extends StatelessWidget {
  // 新增控制器属性
  final TextEditingController controller;
  const TextInputField({
    Key? key,
    // 要求调用时必须传入控制器
    required this.controller,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    Size size = MediaQuery.of(context).size;
    return Padding(
      padding: const EdgeInsets.symmetric(vertical: 10.0),
      child: Container(
        height: size.height * 0.08,
        width: size.width * 0.8,
        decoration: BoxDecoration(
          color: Colors.grey[500],
          borderRadius: BorderRadius.circular(16),
        ),
        child: TextField(
          // 替换为传入的控制器
          controller: controller,
          decoration: InputDecoration(
            border: InputBorder.none,
            prefixIcon: Padding(
              padding: const EdgeInsets.symmetric(horizontal: 20.0),
              child: Icon(
                FontAwesomeIcons.user,
                size: 28,
                color: Colors.black54,
              ),
            ),
            hintText: 'id',
          ),
        ),
      ),
    );
  }
}

PasswordInput按照同样的逻辑修改即可。

步骤2:父组件调用时传入对应控制器

在_LoginState中使用自定义输入组件时,把提前定义好的控制器传入:

class _LoginState extends State<LoginScreen> {
  final userId = TextEditingController();
  final userPass = TextEditingController();

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        // 传入账号控制器
        TextInputField(controller: userId),
        // 传入密码控制器
        PasswordInput(controller: userPass),
        LoginButton()
      ],
    );
  }
}

步骤3:调整登录方法位置和取值逻辑

把loginAct方法放到_LoginState类内部,同时通过控制器的text属性获取输入的文本值:

class _LoginState extends State<LoginScreen> {
  final userId = TextEditingController();
  final userPass = TextEditingController();

  // 登录方法放到State内部
  void loginAct() async {
    var data = {
      "user_id": userId.text,
      "user_pass": userPass.text,
    };
    // 后续接口请求逻辑
  }

  @override
  void dispose() {
    // 页面销毁时释放控制器,避免内存泄漏
    userId.dispose();
    userPass.dispose();
    super.dispose();
  }

  // 原有build逻辑
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 14:15:02