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

Flutter注册页面输入框空校验不生效及死代码问题如何解决

问题根因

你的代码存在3处核心错误,直接导致预期逻辑无法生效:

  • 所有TextEditingController、空值标记布尔变量、dispose生命周期方法都错误定义在build方法内部。build方法每次UI重绘都会重新执行,所有变量都会被重置为初始值,IDE判定三元表达式的判断分支为死代码正是因为这个原因——在单次build的作用域内,布尔变量永远是初始的false,不会变化。
  • 点击注册按钮修改布尔标记后,没有调用setState方法触发UI重绘,就算变量位置正确,错误提示也不会显示。
  • 点击注册按钮没有加校验判断逻辑,不管输入是否符合要求,都会直接执行页面跳转。

修改后的完整代码

import 'package:club_mark_2/styles/style.dart';
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';

import 'userPreferences/user_details_preference.dart';

class RegisterScreen extends StatefulWidget {
  const RegisterScreen({Key? key}) : super(key: key);

  @override
  _RegisterScreenState createState() => _RegisterScreenState();
}

class _RegisterScreenState extends State<RegisterScreen> {
  // 把控制器、状态变量移到build外部,作为State类的成员变量
  final registerEmail = TextEditingController();
  final registerPassword = TextEditingController();
  final verifyPassword = TextEditingController();
  final registerName = TextEditingController();
  bool _emptyboxmail = false;
  bool _emptyboxpass = false;
  bool _emptyboxverify = false;
  bool _emptyboxregistername = false;

  // dispose生命周期方法放在类内部,build外部
  @override
  void dispose() {
    registerEmail.dispose();
    registerPassword.dispose();
    verifyPassword.dispose();
    registerName.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    double width = MediaQuery.of(context).size.width;
    double height = MediaQuery.of(context).size.height;
    return Scaffold(
      backgroundColor: Colors.transparent,
      body: SizedBox(
        width: width,
        height: height,
        child: Stack(children: <Widget>[
          Padding(
            padding: const EdgeInsets.only(left: 15, top: 165, right: 15),
            child: ListView(
              children: [
                Center(
                  child: Text(
                    'SIGN UP',
                    style: TextStyle(
                      color: Colors.white,
                      fontSize: 30.0,
                      fontWeight: FontWeight.bold,
                      fontFamily: 'Montserrat',
                    ),
                  ),
                ),
                Container(
                  padding: EdgeInsets.all(8.0),
                  child: TextFormField(
                    style: TextStyle(color: Colors.white),
                    decoration: InputDecoration(
                      errorText: _emptyboxregistername
                          ? 'field cannot be empty'
                          : null,
                      enabledBorder: OutlineInputBorder(
                          borderSide:
                          BorderSide(color: Colors.grey.withOpacity(0.5)),
                          borderRadius: BorderRadius.circular(20)),
                      hintText: 'Full Name',
                      hintStyle: TextStyle(color: kcMediumGreyColor),
                      labelStyle: TextStyle(color: Colors.white),
                      prefixIcon: const Icon(
                        Icons.person,
                        color: Colors.white,
                      ),
                    ),
                    controller: registerName,
                  ),
                ),
                SizedBox(
                  height: 5,
                ),
                Container(
                  padding: EdgeInsets.all(8.0),
                  child: TextFormField(
                    style: TextStyle(color: Colors.white),
                    decoration: InputDecoration(
                      errorText: _emptyboxmail ? 'field cannot be empty' : null,
                      enabledBorder: OutlineInputBorder(
                        borderSide:
                        BorderSide(color: Colors.grey.withOpacity(0.5)),
                        borderRadius: BorderRadius.circular(20),
                      ),
                      hintText: 'E-mail',
                      hintStyle: TextStyle(color: kcMediumGreyColor),
                      labelStyle: TextStyle(color: Colors.white),
                      prefixIcon: const Icon(
                        Icons.email,
                        color: Colors.white,
                      ),
                    ),
                    controller: registerEmail,
                  ),
                ),
                SizedBox(
                  height: 5,
                ),
                Container(
                  padding: EdgeInsets.all(8.0),
                  child: TextFormField(
                    style: TextStyle(color: Colors.white),
                    obscureText: true,
                    decoration: InputDecoration(
                      errorText: _emptyboxpass ? 'field cannot be empty' : null,
                      enabledBorder: OutlineInputBorder(
                        borderSide:
                        BorderSide(color: Colors.grey.withOpacity(0.5)),
                        borderRadius: BorderRadius.circular(20),
                      ),
                      hintText: 'Password',
                      hintStyle: TextStyle(color: kcMediumGreyColor),
                      labelStyle: TextStyle(
                        color: Colors.white,
                      ),
                      prefixIcon: const Icon(
                        Icons.lock,
                        color: Colors.white,
                      ),
                    ),
                    controller: registerPassword,
                  ),
                ),
                SizedBox(
                  height: 5,
                ),
                Container(
                  padding: EdgeInsets.all(8.0),
                  child: TextFormField(
                    style: TextStyle(color: Colors.white),
                    obscureText: true,
                    decoration: InputDecoration(
                      errorText:
                      _emptyboxverify ? 'field cannot be empty' : null,
                      enabledBorder: OutlineInputBorder(
                        borderSide:
                        BorderSide(color: Colors.grey.withOpacity(0.5)),
                        borderRadius: BorderRadius.circular(20),
                      ),
                      hintText: 'Verify Password',
                      hintStyle: TextStyle(color: kcMediumGreyColor),
                      labelStyle: TextStyle(color: Colors.white),
                      prefixIcon: const Icon(
                        Icons.lock,
                        color: Colors.white,
                      ),
                    ),
                    controller: verifyPassword,
                  ),
                ),
                SizedBox(
                  height: 20,
                ),
                SizedBox(
                  height: 60,
                  child: TextButton(
                    style: ButtonStyle(
                      shape: MaterialStateProperty.all<RoundedRectangleBorder>(
                        RoundedRectangleBorder(
                          borderRadius: BorderRadius.circular(18.0),
                        ),
                      ),
                    ),
                    onPressed: () {
                      // 修改状态后调用setState触发重绘
                      setState(() {
                        _emptyboxmail = registerEmail.text.isEmpty;
                        _emptyboxregistername = registerName.text.isEmpty;
                        _emptyboxpass = registerPassword.text.isEmpty;
                        _emptyboxverify = verifyPassword.text.isEmpty;
                      });
                      // 加校验判断,所有输入都不为空才跳转
                      if(!_emptyboxmail && !_emptyboxregistername && !_emptyboxpass && !_emptyboxverify) {
                        Navigator.push(
                          context,
                          MaterialPageRoute(
                            builder: (context) => UserDetailsPreference(),
                          ),
                        );
                      }
                    },
                    child: Text('Sign Up'),
                  ),
                ),
                SizedBox(
                  height: 20,
                ),
                Row(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: [
                    Container(
                      padding: EdgeInsets.all(8.0),
                      child: Text(
                        "━━━━━  OR SIGN UP WITH  ━━━━━",
                        style: TextStyle(color: kcMediumGreyColor),
                      ),
                    ),
                  ],
                ),
                SizedBox(
                  height: 20,
                ),
                Row(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: [
                    InkWell(
                      onTap: () {},
                      child: Container(
                        decoration: BoxDecoration(),
                        child: ClipRRect(
                          borderRadius: BorderRadius.circular(10.0),
                          child: Image.asset('lib/assets/images/googleIcon.png',
                              width: 50.0, height: 50.0),
                        ),
                      ),
                    ),
                    SizedBox(
                      width: 30,
                    ),
                    InkWell(
                      onTap: () {},
                      child: Container(
                        decoration: BoxDecoration(),
                        child: ClipRRect(
                          child: Image.asset(
                              'lib/assets/images/facebookIcon.png',
                              width: 45.0,
                              height: 45.0),
                        ),
                      ),
                    ),
                  ],
                ),
                SizedBox(
                  height: 20,
                ),
                Row(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: [
                    Container(
                      padding: EdgeInsets.all(8.0),
                      child: Text(
                        "Already have an account?",
                        style: TextStyle(color: Colors.white),
                      ),
                    ),
                    Text(
                      "SIGN IN",
                      style: TextStyle(color: kcPrimaryColor),
                    ),
                  ],
                ),
              ],
            ),
          ),
        ]),
      ),
    );
  }
}

额外优化说明

你还可以给TextFormField加上onChanged回调,在用户输入内容后自动隐藏对应错误提示,使用体验更好:

onChanged: (val) {
  if(_emptyboxregistername && val.isNotEmpty) {
    setState(() => _emptyboxregistername = false);
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 14:00:03