轻按TextField之一可清除TextField文本

时间:2019-06-05 10:38:54

标签: flutter flutter-layout

我遇到了一个奇怪的问题,如果您单击它,TextField总是会被清除。

class MyEditText extends StatefulWidget {
  static String tag = "MyEditText";
  @override
  MyEditTextState createState() => MyEditTextState();
}

class MyEditTextState extends State<MyEditText> {
  String results = "";
  final TextEditingController controller = new TextEditingController();
  final TextEditingController controller1 = new TextEditingController();

  @override
  Widget build(BuildContext context) {
    final email = TextField(
      decoration: InputDecoration(
          hintText: 'Enter Email',
          contentPadding: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0)),
    );

    final password = TextField(
      obscureText: true,
      decoration: InputDecoration(
        hintText: 'Enter Password',
        contentPadding: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0),
      ),
    );

    return new Scaffold(
      appBar: new AppBar(
        automaticallyImplyLeading: false,
        title: new Text("EditText Sample"),
        backgroundColor: Colors.yellow,
      ),
      body: new Container(
        child: new Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: <Widget>[email, password],
        ),
      ),
    );
  }
}

我正在为其使用statful小部件,并且此屏幕启动时的所有类也都为statful。

注意:如果我注释掉所有TextEditingController及其用法,则一切正常,因此我不会弄明白TextEditingController出了什么问题

3 个答案:

答案 0 :(得分:1)

感谢更新的代码。

清除TextEditingController的原因是因为您在State<MyEditText>内声明了变量。当国家重新初始化时-这些变量也是如此。

我可以看到两种解决方法:

#1-将控制器从State移到父类,将其作为参数传递

在父类的MyEditText小部件外部声明和维护控制器。

class MyEditText extends StatefulWidget {
  MyEditText({ Key key, this.emailController, this.passwordController }): super(key: key);

  final TextEditingController emailController;
  final TextEditingController passwordController;

  static String tag = "MyEditText";

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

class MyEditTextState extends State<MyEditText> {
  String results = "";

  @override
  Widget build(BuildContext context) {
    // ...
    TextField(
      controller: widget.emailController,
      // ...,
    ),
    TextField(
      controller: widget.passwordController,
      // ...,
    ),
    // ...
  }
}

然后,您在父类中声明控制器,并将其作为参数传递给MyEditText

final emailController = TextEditingController();
final passwordController = TextEditingController();
// ...
MyEditText(
  emailController: emailController,
  passwordController: passwordController,
)

#2-在didUpdateWidget调用中从旧状态重用控制器

可以在MyEditText类之外声明控制器,但如果不是,则-窗口小部件自行创建和维护TextEditingController

class MyEditText extends StatefulWidget {
  MyEditText({ Key key, this.emailController, this.passwordController }): super(key: key);

  final TextEditingController emailController;
  final TextEditingController passwordController;

  static String tag = "MyEditText";

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

class MyEditTextState extends State<MyEditText> {

  TextEditingController _emailController;
  TextEditingController _passwordController;

  @override
  void initState() {
    super.initState();
    if (widget.emailController == null)
      _emailController = TextEditingController();
    if (widget.passwordController == null)
      _passwordController = TextEditingController();
  }

  @override
  void didUpdateWidget(MyEditText oldWidget) {
    super.didUpdateWidget(oldWidget);

    if (widget.emailController == null && oldWidget.emailController != null)
      _emailController = TextEditingController.fromValue(oldWidget.emailController.value);
    else if (widget.emailController != null && oldWidget.emailController == null)
      _emailController = null;

    if (widget.passwordController == null && oldWidget.passwordController != null)
      _passwordController = TextEditingController.fromValue(oldWidget.passwordController.value);
    else if (widget.passwordController != null && oldWidget.passwordController == null)
      _passwordController = null;
  }

  @override
  Widget build(BuildContext context) {
    // ...
    TextField(
      controller: _emailController ?? widget.emailController,
      // ...,
    ),
    TextField(
      controller: _passwordController ?? widget.passwordController,
      // ...,
    ),
    // ...
  }
  // ...
}

除了第二种方法自行调节State<MyEditText>变量之外,这两种方法都是相似的。

我将由您决定哪个更适合您的情况。

让我知道这是否有帮助。

答案 1 :(得分:0)

 

   TextEditingController controller = TextEditingController();
    TextEditingController controller1 = TextEditingController();

    final email = TextField(
      controller: emailController,
      keyboardType: TextInputType.emailAddress,
      decoration: InputDecoration(
          prefixIcon: Icon(Icons.person_outline, color: Colors.grey),
          hintText: 'Enter Email',
          contentPadding: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0)),
    );

    final password = TextField(
      controller1: passwordController,
      obscureText: true,
      decoration: InputDecoration(
        prefixIcon: Icon(Icons.lock_open, color: Colors.grey),
        hintText: 'Enter Password',
        contentPadding: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0),
      ),
    );

     clearName() {
        controller.text = '';
        controller1.text = '';
     }
 
 //call the clearName function wherever needed

答案 2 :(得分:0)

您可以尝试这种方式

TextFormField(
                cursorColor: Colors.white,
                autofocus: false,
                keyboardType:
                TextInputType.emailAddress,
                controller: _textEditingControllerEmail,
                ),

 TextFormField(
               autofocus: false,
               controller:_textEditingControllerPassword,
               cursorColor: Colors.white,
               obscureText: true,
               ),