0
votes

Comment afficher / masquer le mot de passe dans Flutter?

J'ai créé un écran de connexion pour mon application mais dans le champ du mot de passe, je veux une fonctionnalité comme lorsque je saisis un mot de passe au format * et à droite une icône lorsque l'utilisateur clique dessus, le mot de passe sera visible, j'ai créé un code pour mais quand je clique sur le champ de mot de passe, cette icône devient invisible et lorsque le champ de mot de passe perd le focus que l'icône réapparaît, alors comment toujours afficher cette icône, même le champ de mot de passe est au point? J'ai fourni un instantané pour comprendre facilement le problème.

entrez la description de l'image ici

entrez la description de l'image ici

Voici mon code d'écran de connexion ...

import 'package:flutter/material.dart';
import 'package:email_validator/email_validator.dart';
import 'package:secret_keeper/screens/home_screen/Home.dart';
import 'package:secret_keeper/screens/home_screen/passwords/PasswordsNavigation.dart';
import 'package:secret_keeper/screens/signup_page/SignupPage.dart';

class LoginPage extends StatefulWidget{
  @override
  _LoginPageState createState() => _LoginPageState();
}

class _LoginPageState extends State<LoginPage> {

  String _emailID, _password = "",_email = "abc@gmail.com", _pass = "Try.t.r.y@1";
  bool _obscureText = true;
  final _formKey = GlobalKey<FormState>();
  
  void _toggle(){
    setState(() {
      _obscureText = !_obscureText;
    });
  }

  void validateLogin(){
    if(_formKey.currentState.validate()){
      _formKey.currentState.save();
      if(_emailID == _email && _password == _pass){
        Navigator.pushReplacement(context, MaterialPageRoute(builder: (context) => Home()));
      }
    }
  }

  Widget emailInput(){
    return TextFormField(
      keyboardType: TextInputType.emailAddress,
      decoration: InputDecoration(
        labelText: "Email ID",
        labelStyle: TextStyle(fontSize: 14,color: Colors.grey.shade400),
        enabledBorder: OutlineInputBorder(
          borderRadius: BorderRadius.circular(10),
          borderSide: BorderSide(
            color: Colors.grey.shade300,
          ),
        ),
        focusedBorder: OutlineInputBorder(
            borderRadius: BorderRadius.circular(10),
            borderSide: BorderSide(
              color: Colors.red,
            )
        ),
      ),
      validator: (email) {
        if (email.isEmpty)
          return 'Please Enter email ID';
        else if (!EmailValidator.validate(email))
          return 'Enter valid email address';
        else
          return null;
      },
      onSaved: (email)=> _emailID = email,
      textInputAction: TextInputAction.next,
    );
  }

  Widget passInput(){
    return TextFormField(
      keyboardType: TextInputType.text,
      decoration: InputDecoration(
        labelText: "Password",
        labelStyle: TextStyle(fontSize: 14,color: Colors.grey.shade400),
        enabledBorder: OutlineInputBorder(
          borderRadius: BorderRadius.circular(10),
          borderSide: BorderSide(
            color: Colors.grey.shade300,
          ),
        ),
        focusedBorder: OutlineInputBorder(
          borderRadius: BorderRadius.circular(10),
          borderSide: BorderSide(
            color: Colors.red,
          )
        ),
        suffixIcon: IconButton(
          icon: Icon(
            _obscureText ? Icons.visibility : Icons.visibility_off,
          ),
          onPressed: _toggle,
        ),
      ),
      validator: (password){
        Pattern pattern =
            r'^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[!@#\$&*~]).{8,}$';
        RegExp regex = new RegExp(pattern);
        if (password.isEmpty){
          return 'Please Enter Password';
        }else if (!regex.hasMatch(password))
          return 'Enter valid password';
        else
          return null;
      },
      onSaved: (password)=> _password = password,
      textInputAction: TextInputAction.done,
      obscureText: _obscureText,
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      resizeToAvoidBottomPadding: false,
      backgroundColor: Colors.white,
      body: SafeArea(
        child: Container(
          padding: EdgeInsets.only(left: 16,right: 16),
          child: Form(
            key: _formKey,
            child: Column(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              crossAxisAlignment: CrossAxisAlignment.start,
              children: <Widget>[
                Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: <Widget>[
                    SizedBox(height: 50,),
                    Text("Welcome,",style: TextStyle(fontSize: 26,fontWeight: FontWeight.bold),),
                    SizedBox(height: 6,),
                    Text("Sign in to continue!",style: TextStyle(fontSize: 20,color: Colors.grey.shade400),),
                  ],
                ),
                Column(
                  children: <Widget>[
                    emailInput(),
                    SizedBox(height: 16,),
                    passInput(),
                    SizedBox(height: 12,),
                    Align(
                      alignment: Alignment.topRight,
                      child: Text("Forgot Password ?",style: TextStyle(fontSize: 14,fontWeight: FontWeight.w600),),
                    ),
                    SizedBox(height: 30,),
                    Container(
                      height: 50,
                      width: double.infinity,
                      child: FlatButton(
                        onPressed: validateLogin,
                        padding: EdgeInsets.all(0),
                        child: Ink(
                          decoration: BoxDecoration(
                            borderRadius: BorderRadius.circular(6),
                            gradient: LinearGradient(
                              begin: Alignment.centerLeft,
                              end: Alignment.centerRight,
                              colors: [
                                Color(0xffff5f6d),
                                Color(0xffff5f6d),
                                Color(0xffffc371),
                              ],
                            ),
                          ),
                          child: Container(
                            alignment: Alignment.center,
                            constraints: BoxConstraints(maxWidth: double.infinity,minHeight: 50),
                            child: Text("Login",style: TextStyle(color: Colors.white,fontWeight: FontWeight.bold),textAlign: TextAlign.center,),
                          ),
                        ),
                        shape: RoundedRectangleBorder(
                          borderRadius: BorderRadius.circular(6),
                        ),
                      ),
                    ),
                    SizedBox(height: 16,),
                    Container(
                      height: 50,
                      width: double.infinity,
                      child: FlatButton(
                        onPressed: (){},
                        color: Colors.indigo.shade50,
                        shape: RoundedRectangleBorder(
                          borderRadius: BorderRadius.circular(6),
                        ),
                        child: Row(
                          mainAxisAlignment: MainAxisAlignment.center,
                          children: <Widget>[
                            Image.asset("assets/images/facebook.png",height: 18,width: 18,),
                            SizedBox(width: 10,),
                            Text("Connect with Facebook",style: TextStyle(color: Colors.indigo,fontWeight: FontWeight.bold),),
                          ],
                        ),
                      ),
                    ),
                    SizedBox(height: 16,),
                    Container(
                      height: 50,
                      width: double.infinity,
                      child: FlatButton(
                        onPressed: (){},
                        color: Colors.indigo.shade50,
                        shape: RoundedRectangleBorder(
                          borderRadius: BorderRadius.circular(6),
                        ),
                        child: Row(
                          mainAxisAlignment: MainAxisAlignment.center,
                          children: <Widget>[
                            Image.asset("assets/images/facebook.png",height: 18,width: 18,),
                            SizedBox(width: 10,),
                            Text("Connect with Facebook",style: TextStyle(color: Colors.indigo,fontWeight: FontWeight.bold),),
                          ],
                        ),
                      ),
                    ),
                  ],
                ),
                Padding(
                  padding: EdgeInsets.only(bottom: 10),
                  child: Row(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: <Widget>[
                      Text("Don't have an account?",style: TextStyle(fontWeight: FontWeight.bold),),
                      SizedBox(width: 5,),
                      GestureDetector(
                        onTap: (){
                          Navigator.push(context, MaterialPageRoute(builder: (context){
                            return SignupPage();
                          }));
                        },
                        child: Text("Sign up",style: TextStyle(fontWeight: FontWeight.bold,color: Colors.red),),
                      )
                    ],
                  ),
                )
              ],
            ),
          ),
        ),
      ),
    );
  }
}


0 commentaires

3 Réponses :


0
votes

vous pouvez mettre le champ de texte et le bouton icône dans une pile, remplacer ce code par votre champ de texte de mot de passe. vous pouvez changer la position du bouton d'icône à ce que vous voulez.

Stack(
      children: [
        TextFormField(
          keyboardType: TextInputType.text,
          decoration: InputDecoration(
            labelText: "Password",
            labelStyle:
                TextStyle(fontSize: 14, color: Colors.grey.shade400),
            enabledBorder: OutlineInputBorder(
              borderRadius: BorderRadius.circular(10),
              borderSide: BorderSide(
                color: Colors.grey.shade300,
              ),
            ),
            focusedBorder: OutlineInputBorder(
                borderRadius: BorderRadius.circular(10),
                borderSide: BorderSide(
                  color: Colors.red,
                )),
          ),
          validator: (password) {
            Pattern pattern =
                r'^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[!@#\$&*~]).{8,}$';
            RegExp regex = new RegExp(pattern);
            if (password.isEmpty) {
              return 'Please Enter Password';
            } else if (!regex.hasMatch(password))
              return 'Enter valid password';
            else
              return null;
          },
          onSaved: (password) => _password = password,
          textInputAction: TextInputAction.done,
          obscureText: _obscureText,
        ),
        Positioned(
          top: 2,
          right: 10,
          child: IconButton(
              icon: Icon(
                _obscureText ? Icons.visibility : Icons.visibility_off,
              ),
              onPressed: () {
                setState(() {
                  _obscureText = !_obscureText;
                });
              }),
        ),
      ],
    ),


2 commentaires

Bien que cela semble être une bonne solution au début, je ne recommanderais pas cette approche par rapport au suffixIcon déjà fourni. Cette solution pose un problème lorsque l'indication s'anime en haut du TextField, ce qui entraîne à son tour le changement de la hauteur du widget, ce qui fait que l'icône ne se trouve pas au centre du TextField.


Alors que puis-je faire pour résoudre ce problème?



0
votes

Je viens de copier et d'exécuter votre code et cela fonctionne très bien. L'icône était visible lorsque le champ de mot de passe avait le focus. Vous devriez peut-être vérifier votre version de flutter ou cela pourrait probablement être votre émulateur.
flutter --version
Flutter 1.22.3 • canal stable • https://github.com/flutter/flutter.git
Framework • révision 8874f21e79 (il y a 2 semaines) • 2020-10-29 14:14:35 -0700
Moteur • révision a1440ca392
Outils • Dart 2.10.3
J'ai de la concentration et ça marche


1 commentaires

J'utilise également la même version de Flutter 'Flutter 1.22.3 • channel stable • github.com/flutter/flutter.git Framework • révision 8874f21e79 (il y a 2 semaines) • 2020-10-29 14:14:35 -0700 Engine • révision a1440ca392 Outils • Dart 2.10.3 '



0
votes

En fait, l'icône du suffixe est visible, mais lorsque je clique sur TextFormField, la couleur de l'icône devient blanche, donc simplement dans le champ de l'icône, j'ai ajouté une propriété de couleur et donne une couleur noire à l'icône afin que même le champ de texte soit net, sa couleur reste noire.


0 commentaires