Flutter:如果密码不匹配,如何更改文本字段的颜色?

Flutter: How change color of textfields if the passwords don't match?

我是 flutter 的新手,我正在制作注册表单,如果密码不相等,我需要实时更改密码文本字段的颜色,我可能看起来不对,但我可以'找不到如何去做(validator: 除外,但这在 TextField 中不起作用)。

这是一个例子:

我的代码:

import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:http/http.dart' as http;
import 'DashBoard.dart';
import 'main.dart';
import 'package:flutter/services.dart';
//import 'package:email_validator/email_validator.dart';
// import 'package:validators/validators.dart';

class Register extends StatefulWidget {
  @override
  _RegisterState createState() => _RegisterState();
}

class _RegisterState extends State<Register> {
  TextEditingController correo = TextEditingController();
  TextEditingController celular = TextEditingController();
  TextEditingController passwd = TextEditingController();
  TextEditingController passwd2 = TextEditingController();

  Future register() async {
    var url =
        "http://192.168.1.139/mydatabase/register.php"; //IPv4, colocar después el hosting
    var response = await http.post(url, body: {
      "correo": correo.text,
      "celular": celular.text,
      "passwd": passwd.text,
      "passwd2": passwd2.text
    });
    var data = json.decode(response.body);
    if (data == "Error") {
      FlutterToast(context).showToast(
          child: Text(
        'User allready exit!',
        style: TextStyle(fontSize: 25, color: Colors.red),
      ));
    } else {
      FlutterToast(context).showToast(
          child: Text('Registration Successful',
              style: TextStyle(fontSize: 25, color: Colors.green)));
      Navigator.push(
        context,
        MaterialPageRoute(
          builder: (context) => DashBoard(),
        ),
      );
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        height: 900,
        child: Card(
          color: Colors.blue[400],
          child: Column(
            children: <Widget>[
              Padding(
                padding: const EdgeInsets.all(8.0),
                child: Text(
                  'Register',
                  style: TextStyle(fontSize: 25, fontWeight: FontWeight.bold),
                ),
              ),
              Padding(
                padding: const EdgeInsets.all(8.0),
                child: TextField(
                  decoration: InputDecoration(
                    labelText: 'Correo',
                    prefixIcon: Icon(Icons.person),
                    border: OutlineInputBorder(
                        borderRadius: BorderRadius.circular(8)),
                  ),
                  controller: correo,
                ),
              ),
              Padding(
                padding: const EdgeInsets.all(8.0),
                child: TextField(
                  maxLength: 12,
                  inputFormatters: <TextInputFormatter>[
                    FilteringTextInputFormatter.digitsOnly,
                  ],
                  keyboardType: TextInputType.number,
                  decoration: InputDecoration(
                    labelText: 'Celular',
                    prefixIcon: Icon(Icons.person),
                    border: OutlineInputBorder(
                        borderRadius: BorderRadius.circular(8)),
                  ),
                  controller: celular,
                  textInputAction: TextInputAction.done,
                ),
              ),
              Padding(
                padding: const EdgeInsets.all(8.0),
                child: TextField(
                  obscureText: true,
                  decoration: InputDecoration(
                    labelText: 'Contraseña',
                    prefixIcon: Icon(Icons.lock),
                    border: OutlineInputBorder(
                        borderRadius: BorderRadius.circular(8)),
                  ),
                  controller: passwd,
                ),
              ),
              Padding(
                padding: const EdgeInsets.all(8.0),
                child: TextField(
                  obscureText: true,
                  decoration: InputDecoration(
                    labelText: 'Password',
                    prefixIcon: Icon(Icons.lock),
                    border: OutlineInputBorder(
                        borderRadius: BorderRadius.circular(8)),
                  ),
                  controller: passwd2,
                ),
              ),
              Row(
                children: <Widget>[
                  Expanded(
                    child: MaterialButton(
                      color: Colors.pink,
                      child: Text('Register',
                          style: TextStyle(
                              fontSize: 20,
                              fontWeight: FontWeight.bold,
                              color: Colors.white)),
                      onPressed: () {
                        register();
                        passwd.text = "";
                      },
                    ),
                  ),
                  Expanded(
                    child: MaterialButton(
                      color: Colors.amber[100],
                      child: Text('Login',
                          style: TextStyle(
                              fontSize: 20,
                              fontWeight: FontWeight.bold,
                              color: Colors.black)),
                      onPressed: () {
                        Navigator.push(
                          context,
                          MaterialPageRoute(
                            builder: (context) => MyHomePage(),
                          ),
                        );
                      },
                    ),
                  ),
                ],
              )
            ],
          ),
        ),
      ),
    );
  }
}

我的密码的文本域有控制器 passwdpasswd2。有什么建议吗?请你能很好地理解它,我完全是颤振的初学者。谢谢。

您可以在 initState 上使用 .addListenerTextEditingController

一个bool改变ui,你可以用它来设置边框颜色。

passwd2.addListener(() {
  setState(() {
    showError = passwd2.text.isEmpty
        ? false
        : passwd.text.trim() != passwd2.text.trim();
  });
});

您可以通过更换控制器对 passwd 执行相同的操作,只有当您还想从第一个 TextFiled

更改 ui 时才需要
// try with commenting this part
passwd.addListener(() {
  setState(() {
    showError = passwd.text.isEmpty
        ? false
        : passwd.text.trim() != passwd2.text.trim();
  });
});

并且在 Column 里面使用这个 showError bool 这样的方式,它可以是

child: Column(
  children: <Widget>[
    //........
    if (showError) const Text("Password didnot match"),
    //.......

更多关于Listen to the controller for changes

我的代码:

  bool showError = false;

      @override
      void initState() {
        super.initState();
    
        passwd2.addListener(() {
          setState(() {
            showError = passwd2.text.isEmpty
                ? false
                : passwd.text.trim() != passwd2.text.trim();
          });
        });
        passwd.addListener(() {
          setState(() {
            showError = passwd.text.isEmpty
                ? false
                : passwd.text.trim() != passwd2.text.trim();
          });
        });
      }
    
    
     Padding(
        padding: const EdgeInsets.all(8.0),
        child: TextField(
          obscureText: true,
          decoration: InputDecoration(
            labelText: 'Contraseña',
            prefixIcon: Icon(Icons.lock),
            focusedBorder: OutlineInputBorder(
              borderRadius: BorderRadius.circular(8),
              borderSide: BorderSide(color: Colors.blue, width: 2.0),
            ),
            enabledBorder: OutlineInputBorder(
              borderRadius: BorderRadius.circular(8),
              borderSide:
                  BorderSide(color: Colors.blue[900], width: 2.0),
            ),
          ),
          controller: passwd,
        ),
      ),
      Padding(
        padding: const EdgeInsets.all(8.0),
        child: TextField(
          obscureText: true,
          decoration: InputDecoration(
            labelText: 'Repita contraseña',
            prefixIcon: Icon(Icons.lock),
            focusedBorder: OutlineInputBorder(
              borderRadius: BorderRadius.circular(8),
              borderSide: BorderSide(color: Colors.blue, width: 2.0),
            ),
            enabledBorder: OutlineInputBorder(
              borderRadius: BorderRadius.circular(8),
              borderSide:
                  BorderSide(color: Colors.blue[900], width: 2.0),
            ),
          ),
          controller: passwd2,
        ),
      ),
      if (showError)
       const Text(
         "Las contraseñas no coinciden",
       style: TextStyle(color: Colors.red),
      )