Flutter 如何在flatter中显示/隐藏密码?

Flutter 如何在flatter中显示/隐藏密码?,flutter,Flutter,我已经为我的应用程序创建了一个登录屏幕,但在密码字段中,我想要一个功能,比如当我以*格式键入密码时,在右侧有一个图标,当用户单击它时,密码将可见,我为它创建了一个代码,但当我单击密码字段时,图标变得不可见,当密码字段失去焦点时,图标再次出现,那么如何始终显示图标,即使密码字段处于焦点? 我提供了一个快照,以便轻松理解问题 这是我的登录屏幕代码 import 'package:flutter/material.dart'; import 'package:email_validator/ema

我已经为我的应用程序创建了一个登录屏幕,但在密码字段中,我想要一个功能,比如当我以*格式键入密码时,在右侧有一个图标,当用户单击它时,密码将可见,我为它创建了一个代码,但当我单击密码字段时,图标变得不可见,当密码字段失去焦点时,图标再次出现,那么如何始终显示图标,即使密码字段处于焦点? 我提供了一个快照,以便轻松理解问题

这是我的登录屏幕代码

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),),
                      )
                    ],
                  ),
                )
              ],
            ),
          ),
        ),
      ),
    );
  }
}
导入“包装:颤振/材料.省道”;
导入“包:email_validator/email_validator.dart”;
导入“包:秘密守护者/screens/home\u screen/home.dart”;
导入“包:secret_keeper/screens/home_screen/passwords/passwords navigation.dart”;
导入“package:secret_keeper/screens/signup_page/SignupPage.dart”;
类LoginPage扩展StatefulWidget{
@凌驾
_LoginPagentate createState()=>_LoginPagentate();
}
类_loginpagentate扩展状态{
字符串_emailID,_password=“”,_email=”abc@gmail.com“,\u pass=“Try.t.r。y@1";
bool _obsolizeText=true;
final _formKey=GlobalKey();
void _toggle(){
设置状态(){
_蒙蔽文本=!\u蒙蔽文本;
});
}
void validateLogin(){
if(_formKey.currentState.validate()){
_formKey.currentState.save();
如果(\u emailID==\u email&&u password==\u pass){
pushReplacement(context,MaterialPageRoute(builder:(context)=>Home());
}
}
}
小部件emailInput(){
返回TextFormField(
键盘类型:TextInputType.emailAddress,
装饰:输入装饰(
labelText:“电子邮件ID”,
labelStyle:TextStyle(字体大小:14,颜色:Colors.grey.shade400),
enabledBorder:OutlineInputBorder(
边界半径:边界半径。圆形(10),
边界边(
颜色:Colors.grey.shade300,
),
),
聚焦顺序:大纲输入边框(
边界半径:边界半径。圆形(10),
边界边(
颜色:颜色,红色,
)
),
),
验证人:(电子邮件){
如果(email.isEmpty)
返回“请输入电子邮件ID”;
如果(!EmailValidator.validate(电子邮件))
返回“输入有效的电子邮件地址”;
其他的
返回null;
},
onSaved:(email)=>\u emailID=电子邮件,
textInputAction:textInputAction.next,
);
}
Widget passInput(){
返回TextFormField(
键盘类型:TextInputType.text,
装饰:输入装饰(
labelText:“密码”,
labelStyle:TextStyle(字体大小:14,颜色:Colors.grey.shade400),
enabledBorder:OutlineInputBorder(
边界半径:边界半径。圆形(10),
边界边(
颜色:Colors.grey.shade300,
),
),
聚焦顺序:大纲输入边框(
边界半径:边界半径。圆形(10),
边界边(
颜色:颜色,红色,
)
),
后缀:图标按钮(
图标:图标(
_遮挡文字?图标.可见性:图标.可见性关闭,
),
按下按钮:_切换,
),
),
验证器:(密码){
图案=
r'^(?=.[A-Z])(?=.[A-Z])(?=.[0-9])(?=.[!@\$&*~])。{8,}$;
RegExp regex=新的RegExp(模式);
if(password.isEmpty){
返回“请输入密码”;
}如果(!regex.hasMatch(密码))
返回“输入有效密码”;
其他的
返回null;
},
onSaved:(密码)=>\u密码=密码,
textInputAction:textInputAction.done,
蒙蔽文本:_蒙蔽文本,
);
}
@凌驾
小部件构建(构建上下文){
返回脚手架(
resizeToAvoidBottomPadding:false,
背景颜色:Colors.white,
正文:安全区(
子:容器(
填充:仅限边设置(左:16,右:16),
孩子:表格(
键:_formKey,
子:列(
mainAxisAlignment:mainAxisAlignment.spaceBetween,
crossAxisAlignment:crossAxisAlignment.start,
儿童:[
纵队(
crossAxisAlignment:crossAxisAlignment.start,
儿童:[
尺寸箱(高度:50,),
文本(“欢迎”,样式:TextStyle(fontSize:26,fontWeight:fontWeight.bold),
尺寸箱(高度:6,),
文本(“登录以继续!”,样式:TextStyle(fontSize:20,颜色:Colors.grey.shade400),
],
),
纵队(
儿童:[
emailInput(),
尺寸箱(高度:16,),
passInput(),
尺寸箱(高度:12,),
对齐(
对齐:alignment.topRight,
子项:文本(“忘记密码?”,样式:TextStyle(fontSize:14,fontWeight:fontWeight.w600),
),
尺寸箱(高度:30,),
容器(
身高:50,
宽度:double.infinity,
孩子:扁平按钮(
onPressed:validateLogin,
填充:边缘集。全部(0),
孩子:墨水(
装饰:盒子装饰(
边界半径:边界半径。圆形(6),
梯度:线性梯度(
开始:Alignment.centerLeft,
结束:对齐。中间右侧,
颜色:[
颜色(0xffff5f6d),
颜色(0xffff5f6d),
颜色(0xffffc371),
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;
                });
              }),
        ),
      ],
    ),
var passShowButton = GestureDetector(
      onLongPressEnd: outContact,
      onTapDown: inContact, //call this method when incontact
      onTapUp:
          outContact, //call this method when contact with screen is removed
      child: Icon(
        getXHelper.isEmailPasswordUpdate.isTrue
            ? AppIcons.hidePassword
            : AppIcons.hidePassword,
        size: 18,
        color:Colors.grey
      ),
    );
TextField(
    obscureText: getXHelper.isPassInvisible  ,
    autocorrect: false,
    textAlignVertical: TextAlignVertical.bottom,
    decoration: InputDecoration(
      enabled: true,
      errorBorder: UnderlineInputBorder(
          borderSide: BorderSide(color: AppColors.primary)),
      enabledBorder: UnderlineInputBorder(
          borderSide: BorderSide(color: AppColors.primary)),
      focusedBorder: UnderlineInputBorder(
          borderSide: BorderSide(color: AppColors.primary)),
      border: UnderlineInputBorder(
          borderSide: BorderSide(color: AppColors.primary)),
      fillColor: Colors.white,
      filled: true,
      isDense: true,
      prefixIconConstraints: BoxConstraints(maxHeight: 18, minHeight: 18),
      hintText: "Password",
      prefixIcon: Padding(
        padding: const EdgeInsets.only(top: 0, right: 12, bottom: 0),
        child: Icon(Icons.lock, size: 18, color: Colors.grey),
      ),
      suffixIcon: passShowButton,
    ),
    cursorColor: Colors.black,
    style: TextStyle(
        color: Colors.black, fontFamily: AppFontFamily.fontFamily),
  )
var passShowButton = GestureDetector(
          onLongPressEnd: outContact,
          onTapDown: inContact, //call this method when incontact
          onTapUp:
              outContact, //call this method when contact with screen is removed
          child: Icon(
            getXHelper.isEmailPasswordUpdate.isTrue
                ? AppIcons.hidePassword
                : AppIcons.hidePassword,
            size: 18,
          ),
        );

TextField(
    obscureText: getXHelper.isPassInvisible  ,
    autocorrect: false,
    textAlignVertical: TextAlignVertical.bottom,
    decoration: InputDecoration(
      enabled: true,
      errorBorder: UnderlineInputBorder(
          borderSide: BorderSide(color: AppColors.primary)),
      enabledBorder: UnderlineInputBorder(
          borderSide: BorderSide(color: AppColors.primary)),
      focusedBorder: UnderlineInputBorder(
          borderSide: BorderSide(color: AppColors.primary)),
      border: UnderlineInputBorder(
          borderSide: BorderSide(color: AppColors.primary)),
      fillColor: Colors.white,
      filled: true,
      isDense: true,
      prefixIconConstraints: BoxConstraints(maxHeight: 18, minHeight: 18),
      hintText: "Password",
      prefixIcon: Padding(
        padding: const EdgeInsets.only(top: 0, right: 12, bottom: 0),
        child: Icon(Icons.lock, size: 18),
      ),
      suffixIcon: passShowButton,
    ),
    cursorColor: Colors.black,
    style: TextStyle(
        color: Colors.black, fontFamily: AppFontFamily.fontFamily),
  )
bool _passwordInVisible = true; //a boolean value

TextFormField buildPasswordFormField() {
return TextFormField(
  obscureText: _passwordInVisible,
  onSaved: (newValue) => registerRequestModel.password = newValue,
  onChanged: (value) {
    if (value.isNotEmpty) {
      removeError(error: kPassNullError);
    } else if (value.length >= 8) {
      removeError(error: kShortPassError);
    }
    return null;
  },
  validator: (value) {
    if (value.isEmpty) {
      addError(error: kPassNullError);
      return "";
    } else if (value.length < 8) {
      addError(error: kShortPassError);
      return "";
    }
    return null;
  },
  textInputAction: TextInputAction.next,
  decoration: InputDecoration(
    border: OutlineInputBorder(),
    labelText: "Password",
    hintText: "Enter your password",
    contentPadding: new EdgeInsets.symmetric(vertical: 5.0, horizontal: 15.0),
    floatingLabelBehavior: FloatingLabelBehavior.always,
    suffixIcon: IconButton(
      icon: Icon(
        _passwordInVisible ? Icons.visibility_off : Icons.visibility, //change icon based on boolean value
        color: Theme.of(context).primaryColorDark, 
      ),
      onPressed: () {
        setState(() {
          _passwordInVisible = !_passwordInVisible; //change boolean value
        });
      },
    ),
  ),
);