颤抖,隐藏虚拟键盘时文本字段值变空

时间:2020-10-30 10:28:06

标签: flutter flutter-text

我正在尝试为我的应用创建登录和注册页面,我在两个屏幕上都使用statefull小部件。 填写注册或登录表单并隐藏键盘以按下注册或登录按钮后,即时通讯会收到“字符串为空”的结果,同样在按下时,我尝试在控制台中打印我的电子邮件和密码,但即时通讯处却显示为空。但是,如果我在虚拟设备中仍打开虚拟键盘的情况下尝试这样做,就无法打印出字符串,据我了解,仅当隐藏键盘时才会发生错误。 这是我的输入字段类


    class RoundedInputField extends StatefulWidget {
  final String hintText;
  final ValueChanged<String> onChanged;
  final Color color;
  final bool boolean;

  RoundedInputField({
    Key key,
    this.hintText,
    this.onChanged,
    this.color,
    this.boolean = false,
  }) : super(key: key);

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

class _RoundedInputFieldState extends State<RoundedInputField> {
  @override
  Widget build(BuildContext context) {
    return TextFieldContainer(
      child: TextFormField(
        onChanged: widget.onChanged,
        obscureText: widget.boolean,
        decoration: InputDecoration(
          hintText: widget.hintText,
          border: InputBorder.none,
        ),
      ),
    );
  }
}

class TextFieldContainer extends StatefulWidget {
  final Widget child;
  final Color color;

  const TextFieldContainer({
    Key key,
    this.child,
    this.color: Colors.white,
  }) : super(key: key);

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

class _TextFieldContainerState extends State<TextFieldContainer> {
  @override
  Widget build(BuildContext context) {
    Size size = MediaQuery.of(context).size;
    return Container(
      margin: EdgeInsets.symmetric(vertical: 10),
      padding: EdgeInsets.symmetric(horizontal: 20, vertical: 5),
      width: size.width * 0.8,
      decoration: BoxDecoration(
        color: widget.color,
        borderRadius: BorderRadius.circular(29),
      ),
      child: widget.child,
    );
  }
}




然后我叫RoundedInputField

 RoundedInputField(
              hintText: "Email",
              onChanged: (val) {
                email = val;
              },

这是我的注册按钮,目前仅显示值


Container(
              margin: EdgeInsets.symmetric(vertical: 10),
              width: size.width * 0.8,
              child: ClipRRect(
                borderRadius: BorderRadius.circular(29),
                child: FlatButton(
                  padding: EdgeInsets.symmetric(vertical: 20, horizontal: 40),
                  color: Colors.white,
                  onPressed: () async {
                    
                    print(email);
                    print(password);
                   
                    
                  },
                  child: Text(
                    'login',
                    style: GoogleFonts.montserrat(
                        color: HexColor(studentPrimaryColour), fontSize: 20),
                  ),
                ),
              ),
            ),


这是我的登录屏幕


class StudentLoginScreen extends StatefulWidget {
  StudentLoginScreen();

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

class _StudentLoginScreenState extends State<StudentLoginScreen> {
  @override
  Widget build(BuildContext context) {
    final AuthService _authService = AuthService();
    Size size = MediaQuery.of(context).size;
    String email = '';
    String password = '';
    return Scaffold(
      backgroundColor: HexColor(studentPrimaryColour),
      body: SafeArea(
        child: ListView(
          children: <Widget>[
            SizedBox(
              height: 25.0,
            ),
            HeadingText(
              text: 'Login',
              size: 60.0,
              color: Colors.white,
            ),
            SizedBox(
              height: 25.0,
            ),
            RoundedInputField(
              hintText: "Email",
              onChanged: (val) {
                email = val;
              },
            ),
            SizedBox(
              height: 5.0,
            ),
            RoundedInputField(
              hintText: "Password",
              boolean: true,
              onChanged: (val) {
                password = val;
              },
            ),
            SizedBox(
              height: 15.0,
            ),
            Container(
              margin: EdgeInsets.symmetric(vertical: 10),
              width: size.width * 0.8,
              child: ClipRRect(
                borderRadius: BorderRadius.circular(29),
                child: FlatButton(
                  padding: EdgeInsets.symmetric(vertical: 20, horizontal: 40),
                  color: Colors.white,
                  onPressed: () async {
                    
                    print(email);
                    print(password);
                   

                   
                  },
                  child: Text(
                    'login',
                    style: GoogleFonts.montserrat(
                        color: HexColor(studentPrimaryColour), fontSize: 20),
                  ),
                ),
              ),
            ),
            SizedBox(
              height: 15.0,
            ),
            InkWell(
              onTap: () {
                Navigator.pushNamed(context, '/studentRegisterScreen');
              },
              child: HeadingText(
                text: 'register?',
                color: Colors.white,
                size: 10,
              ),
            ),
          ],
        ),
      ),
    );
  }
}



1 个答案:

答案 0 :(得分:0)

在登录屏幕中,您声明并初始化了email方法内的属性passwordbuild。这实际上意味着,一旦重新构建登录小部件(例如,由于Flutter必须重新计算大小等原因而隐藏键盘时),这两个属性都将再次用''。

初始化。

这就是StatefulWidget的意思-将属性定义为状态的一部分,而不是构建周期的一部分。换句话说,将其更改为:

class StudentLoginScreen extends StatefulWidget {
  StudentLoginScreen();

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

class _StudentLoginScreenState extends State<StudentLoginScreen> {
  String email = '';
  String password = '';

  @override
  Widget build(BuildContext context) {
  ...
}