【问题标题】:Issue in getting value from textfield in flutter从颤动的文本字段中获取价值的问题
【发布时间】:2019-07-12 14:27:48
【问题描述】:

我是新来的颤振。 我正在尝试放置 2 个文本字段,即电子邮件和密码。 和一个登录按钮。 如果用户单击登录按钮,我想检查文本字段中的值。如果是“用户名和密码 = admin”,我想打印一条消息“登录成功”。 为了获取文本字段中的值,我使用 controller 来获取文本。但是如果我在切换到下一个文本字段时使用控制器,则第一个中的值会自动删除。不知道是什么问题。

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'stacked_icons.dart';
import 'main.dart';

class LoginPage extends StatelessWidget {
final emailController =  TextEditingController();
final passwordController = TextEditingController();

@override
Widget build(BuildContext context) {    SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle.dark.copyWith(
  statusBarColor: Colors.orange, //or set color with: Color(0xFF0000FF)
));

return new Scaffold(
  appBar: new AppBar(
      backgroundColor:Colors.transparent,
      elevation: 0.0,
      iconTheme: new IconThemeData(color: Color(0xFF18D191))),
  body: Container(
    width: double.infinity,
    child: new Column(
      crossAxisAlignment: CrossAxisAlignment.center,
      children: <Widget>[
        new StakedIcons(),
        new Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Padding(
              padding: const EdgeInsets.only(top: 8.0, bottom: 80.0),
              child: new Text(
                "Village",
                style: new TextStyle(fontSize: 30.0),
              ),
            )
          ],
        ),
        Padding(
          padding:
          const EdgeInsets.symmetric(horizontal: 20.0, vertical: 0.0),

          child: TextField(

              controller: emailController,
            decoration:
            new InputDecoration(labelText: 'Email'),
          ),
        ),
        new SizedBox(
          height: 15.0,
        ),
        Padding(
          padding:
          const EdgeInsets.symmetric(horizontal: 20.0, vertical: 0.0),
          child: TextField(
            obscureText: true,
            decoration: InputDecoration(labelText: 'Password'),
            //controller: passwordController
          ),
        ),
        new Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Expanded(
              child: Padding(
                padding: const EdgeInsets.only(
                    left: 20.0, right: 5.0, top: 10.0),
                child: GestureDetector(
                  onTap: () {
                    debugPrint(passwordController.text+emailController.text);
                 },
                  child: new Container(
                      alignment: Alignment.center,
                      height: 60.0,
                      decoration: new BoxDecoration(
                          color: Color(0xFF18D191),
                          borderRadius: new BorderRadius.circular(9.0)),
                      child: new Text("Login",
                          style: new TextStyle(
                              fontSize: 20.0, color: Colors.white))),
                ),
              ),
            ),
            Expanded(
              child: Padding(
                padding: const EdgeInsets.only(
                    left: 10.0, right: 20.0, top: 10.0),
                child: new Container(
                    alignment: Alignment.center,
                    height: 60.0,
                    child: new Text("Forgot Password?",
                        style: new TextStyle(
                            fontSize: 17.0, color: Color(0xFF18D191)))),
              ),
            )
          ],
        ),
        Expanded(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.end,
            children: <Widget>[
              Padding(
                padding: const EdgeInsets.only(bottom:18.0),
                child: new Text("Create A New Account ",style: new TextStyle(
                    fontSize: 17.0, color: Color(0xFF18D191),fontWeight: FontWeight.bold)),
              ),
            ],
          ),
        )
      ],
    ),
  ),
);}}

如果我移除控制器,则文本字段中的值有效。但如果不使用控制器,我不知道如何获取文本。

【问题讨论】:

    标签: dart flutter textfield


    【解决方案1】:

    您正在使用无状态小部件,这意味着每次 UI 更改时都会创建一个全新的实例,例如当您切换到下一个字段时。这包括您的控制器 - 当您将焦点从一个字段更改为另一个字段时,它们会重新初始化,这就是它们重置为空白值的原因。

    您需要使用有状态小部件,并在 build() 方法之外初始化控制器。这样,当 UI 发生变化时,它会被重建,但小部件的状态(包括您的控制器及其值)会保持不变。

    如果您使用的是 Android Studio,您需要做的就是单击此行上的任意位置class LoginPage extends StatelessWidget {,然后按 Alt+Enter,然后单击“转换为 StatefulWidget”。 VSCode 中也有它的快捷方式,但我不知道。

    【讨论】:

    【解决方案2】:

    听起来您正在寻找TextField https://docs.flutter.io/flutter/material/TextField/TextField.htmlonChanged 参数

    TextField('foo', onChanged((s) => setState(() => myText = s))) 
    

    【讨论】:

      【解决方案3】:

      您应该将emailpassword 字段包装到Form 小部件中,并将它们的类型更改为TextFormField 以提供validator 函数,以便在您按下按钮时调用它:

      final _formKey = GlobalKey<FormState>();
      
      Form(
      
        key: _formKey,
      
       child: Column(
       children: <widget>[
         Padding(
            padding:
            const EdgeInsets.symmetric(horizontal: 20.0, vertical: 0.0),
      
            child: TextFormField(
              controller: emailController,
              decoration:
              new InputDecoration(labelText: 'Email'),
              validator: //Your validator function here
            ),
          ),
          new SizedBox(
            height: 15.0,
          ),
          Padding(
            padding:
            const EdgeInsets.symmetric(horizontal: 20.0, vertical: 0.0),
            child: TextFormField(
              obscureText: true,
              decoration: InputDecoration(labelText: 'Password'),
              //controller: passwordController,
              validator: //Your validator function here
              ),
            ),
            new Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Expanded(
                child: Padding(
                  padding: const EdgeInsets.only(
                      left: 20.0, right: 5.0, top: 10.0),
                  child: GestureDetector(
                    onTap: () {
                      debugPrint(passwordController.text+emailController.text);
                       if(_formKey.currentState.validate()){
                          //This will only be reached if there both fields has valid input
                       }
      
                   },
                    child: new Container(
                        alignment: Alignment.center,
                        height: 60.0,
                        decoration: new BoxDecoration(
                            color: Color(0xFF18D191),
                            borderRadius: new BorderRadius.circular(9.0)),
                        child: new Text("Login",
                            style: new TextStyle(
                                fontSize: 20.0, color: Colors.white))),
                  ),
                ),
              ),
              Expanded(
                child: Padding(
                  padding: const EdgeInsets.only(
                      left: 10.0, right: 20.0, top: 10.0),
                  child: new Container(
                      alignment: Alignment.center,
                      height: 60.0,
                      child: new Text("Forgot Password?",
                          style: new TextStyle(
                              fontSize: 17.0, color: Color(0xFF18D191)))),
                ),
              )
            ],
          ),
          ]
        ),
      ),
      

      这是您的电子邮件字段的validator 函数示例:

       validator: (val) => val.isEmpty ? 'Email is required' : null
      

      val是当前字段上的文本,所以当结果为null时,表单会知道val是有效输入,否则不会提交。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-05-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-09-12
        • 1970-01-01
        相关资源
        最近更新 更多