[英]How to show/hide password in TextFormField?
目前我的密碼TextFormField
是這樣的:
TextFormField(
decoration: const InputDecoration(
labelText: 'Password',
icon: const Padding(
padding: const EdgeInsets.only(top: 15.0),
child: const Icon(Icons.lock),
)),
validator: (val) => val.length < 6 ? 'Password too short.' : null,
onSaved: (val) => _password = val,
obscureText: true,
);
我想要一個像交互這樣的按鈕,它可以使密碼可見和不可見。 我可以在TextFormField
里面做嗎? 或者我將不得不制作一個Stack
小部件來獲得我所需的 UI。 以及關於obscureText
真/假的條件將如何制定?
我已經按照@Hemanth Raj 創建了一個解決方案,但方式更強大。
首先聲明一個bool
變量_passwordVisible
。
啟動_passwordVisible
以false
的initState()
@override
void initState() {
_passwordVisible = false;
}
以下是TextFormField
小部件:
TextFormField(
keyboardType: TextInputType.text,
controller: _userPasswordController,
obscureText: !_passwordVisible,//This will obscure text dynamically
decoration: InputDecoration(
labelText: 'Password',
hintText: 'Enter your password',
// Here is key idea
suffixIcon: IconButton(
icon: Icon(
// Based on passwordVisible state choose the icon
_passwordVisible
? Icons.visibility
: Icons.visibility_off,
color: Theme.of(context).primaryColorDark,
),
onPressed: () {
// Update the state i.e. toogle the state of passwordVisible variable
setState(() {
_passwordVisible = !_passwordVisible;
});
},
),
),
);
首先讓你小部件StatefulWidget
如果它是一個StatelessWidget
。
然后有一個變量bool _obscureText
並將其傳遞給您的TextFormField
。 根據需要使用setState
切換它。
例子:
class _FormFieldSampleState extends State<FormFieldSample> {
// Initially password is obscure
bool _obscureText = true;
String _password;
// Toggles the password show status
void _toggle() {
setState(() {
_obscureText = !_obscureText;
});
}
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text("Sample"),
),
body: new Container(
child: new Column(
children: <Widget>[
new TextFormField(
decoration: const InputDecoration(
labelText: 'Password',
icon: const Padding(
padding: const EdgeInsets.only(top: 15.0),
child: const Icon(Icons.lock))),
validator: (val) => val.length < 6 ? 'Password too short.' : null,
onSaved: (val) => _password = val,
obscureText: _obscureText,
),
new FlatButton(
onPressed: _toggle,
child: new Text(_obscureText ? "Show" : "Hide"))
],
),
),
);
}
}
希望這可以幫助!
歸功於X-Wei ,您可以將小部件創建為單獨的password.dart
:
import 'package:flutter/material.dart';
class PasswordField extends StatefulWidget {
const PasswordField({
this.fieldKey,
this.hintText,
this.labelText,
this.helperText,
this.onSaved,
this.validator,
this.onFieldSubmitted,
});
final Key fieldKey;
final String hintText;
final String labelText;
final String helperText;
final FormFieldSetter<String> onSaved;
final FormFieldValidator<String> validator;
final ValueChanged<String> onFieldSubmitted;
@override
_PasswordFieldState createState() => new _PasswordFieldState();
}
class _PasswordFieldState extends State<PasswordField> {
bool _obscureText = true;
@override
Widget build(BuildContext context) {
return new TextFormField(
key: widget.fieldKey,
obscureText: _obscureText,
maxLength: 8,
onSaved: widget.onSaved,
validator: widget.validator,
onFieldSubmitted: widget.onFieldSubmitted,
decoration: new InputDecoration(
border: const UnderlineInputBorder(),
filled: true,
hintText: widget.hintText,
labelText: widget.labelText,
helperText: widget.helperText,
suffixIcon: new GestureDetector(
onTap: () {
setState(() {
_obscureText = !_obscureText;
});
},
child:
new Icon(_obscureText ? Icons.visibility : Icons.visibility_off),
),
),
);
}
}
稱之為:
import 'package:my_app/password.dart';
String _password;
final _passwordFieldKey = GlobalKey<FormFieldState<String>>();
PasswordField(
fieldKey: _passwordFieldKey,
helperText: 'No more than 8 characters.',
labelText: 'Password *',
onFieldSubmitted: (String value) {
setState(() {
this._password = value;
});
},
),
我通過按住並釋放 longTap 做到了這一點:
bool _passwordVisible;
@override
void initState() {
_passwordVisible = false;
super.initState();
}
// ...
TextFormField(
obscureText: !_passwordVisible,
decoration: InputDecoration(
hasFloatingPlaceholder: true,
filled: true,
fillColor: Colors.white.withOpacity(0.5),
labelText: "Password",
suffixIcon: GestureDetector(
onLongPress: () {
setState(() {
_passwordVisible = true;
});
},
onLongPressUp: () {
setState(() {
_passwordVisible = false;
});
},
child: Icon(
_passwordVisible ? Icons.visibility : Icons.visibility_off),
),
),
validator: (String value) {
if (value.isEmpty) {
return "*Password needed";
}
},
onSaved: (String value) {
_setPassword(value);
},
);
好吧,我個人喜歡一直隱藏密碼,並在您想看到它們時看到,所以這是我用來隱藏/取消隱藏密碼的方法,如果您希望在觸摸時看到密碼 與隱藏圖標,並在您刪除聯系人后立即隱藏,那么這是給您的
//make it invisible globally
bool invisible = true;
//wrap your toggle icon in Gesture Detector
GestureDetector(
onTapDown: inContact,//call this method when incontact
onTapUp: outContact,//call this method when contact with screen is removed
child: Icon(
Icons.remove_red_eye,
color: colorButton,
),
),
void inContact(TapDownDetails details) {
setState(() {
invisible = false;
});
}
void outContact(TapUpDetails details) {
setState(() {
invisible=true;
});
}
我的包https://pub.dev/packages/passwordfield正在使用這種方法
上面代碼的輸出
class SignIn extends StatefulWidget {
@override
_SignInState createState() => _SignInState();
}
class _SignInState extends State<SignIn> {
// Initially password is obscure
bool _obscureText = true;
// Toggles the password show status
void _togglePasswordStatus() {
setState(() {
_obscureText = !_obscureText;
});
}
@override
Widget build(BuildContext context) {
return
Scaffold(
backgroundColor: Colors.brown[100],
appBar: AppBar(
backgroundColor: Colors.brown[400],
elevation: 0.0,
title: Text('Sign In'),
),
body: Container(
padding: EdgeInsets.symmetric(vertical:20.0,horizontal:50.0),
child: Form(
key: _formKey,
child: Column(children: <Widget>[
TextFormField(
decoration: InputDecoration(
hintText: 'Password',
suffixIcon: IconButton(
icon:Icon(_obscureText ? Icons.visibility:Icons.visibility_off,),
onPressed: _togglePasswordStatus,
color: Colors.pink[400],
),
),
validator: (val){
return
val.length < 6 ? 'Enter A Password Longer Than 6 Charchters' :null;
},
obscureText: _obscureText,
onChanged: (val){
setState(() {
password = val.trim();
});
},
),
],),),
),
);
}
}
bool _obscuredText = true;
_toggle(){
setState(() {
_obscuredText = !_obscuredText;
});
}
Widget _createPassword(){
return TextField(
obscureText: _obscuredText,
cursorColor: Colors.black54,
style: TextStyle( color: Colors.black54),
decoration: InputDecoration(
labelStyle: TextStyle(
color: Colors.black54
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Colors.black54
)
),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(5.0)
),
labelText: 'Contraseña',
hintText: 'Contraseña',
suffixIcon: FlatButton(onPressed: _toggle, child:Icon(Icons.remove_red_eye, color: _obscuredText ? Colors.black12 : Colors.black54))
),
onChanged: (value) {
setState(() {
_password = value;
});
},
);
}
希望這可以幫助!
此解決方案可防止在 suffixIcon 中點擊將焦點放在 TextField 上,但如果 TextField 已聚焦並且用戶想要顯示/隱藏密碼,則不會丟失焦點。
import 'package:flutter/material.dart';
class PasswordField extends StatefulWidget {
const PasswordField({Key? key}) : super(key: key);
@override
_PasswordFieldState createState() => _PasswordFieldState();
}
class _PasswordFieldState extends State<PasswordField> {
final textFieldFocusNode = FocusNode();
bool _obscured = false;
void _toggleObscured() {
setState(() {
_obscured = !_obscured;
if (textFieldFocusNode.hasPrimaryFocus) return; // If focus is on text field, dont unfocus
textFieldFocusNode.canRequestFocus = false; // Prevents focus if tap on eye
});
}
@override
Widget build(BuildContext context) {
return TextField(
keyboardType: TextInputType.visiblePassword,
obscureText: _obscured,
focusNode: textFieldFocusNode,
decoration: InputDecoration(
floatingLabelBehavior: FloatingLabelBehavior.never, //Hides label on focus or if filled
labelText: "Password",
filled: true, // Needed for adding a fill color
fillColor: Colors.grey.shade800,
isDense: true, // Reduces height a bit
border: OutlineInputBorder(
borderSide: BorderSide.none, // No border
borderRadius: BorderRadius.circular(12), // Apply corner radius
),
prefixIcon: Icon(Icons.lock_rounded, size: 24),
suffixIcon: Padding(
padding: const EdgeInsets.fromLTRB(0, 0, 4, 0),
child: GestureDetector(
onTap: _toggleObscured,
child: Icon(
_obscured
? Icons.visibility_rounded
: Icons.visibility_off_rounded,
size: 24,
),
),
),
),
);
}
}
這是一個帶有內置材料設計圖標的簡單示例:
child: TextFormField(
decoration: InputDecoration(
fillColor: Color(0xFFFFFFFF), filled: true,
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Color(0xFF808080)),
),
suffixIcon: GestureDetector(
onTap: () {
setState(() {
_showPassword = !_showPassword;
});
},
child: Icon(
_showPassword ? Icons.visibility : Icons.visibility_off,
),
),
labelText: 'Password'),
obscureText: !_showPassword,
),
感謝@Parikshit Chalke 的回答。 但是,如果您只想更新您的TextFormField
和IconButton
, setState
是非常昂貴的調用。 相反,將它包裝在StatefulBuilder 中並且只更新子項。
示例解決方案:
import 'package:flutter/material.dart';
class MyWidget extends StatefulWidget {
@override
_MyWidgetState createState() => _MyWidgetState();
}
class _MyWidgetState extends State<MyWidget> {
// initially password is invisible
bool _passwordVisible = false;
String _password;
@override
Widget build(BuildContext context) {
return Column(
children: [
// other widget that does not need update when password visibility is toggled
Text("I do not require update"),
StatefulBuilder(builder: (_context, _setState) {
// only following widget gets update when _setState is used
return TextFormField(
decoration: InputDecoration(
suffixIcon: IconButton(
icon: Icon(
_passwordVisible ? Icons.visibility : Icons.visibility_off,
),
onPressed: () {
// use _setState that belong to StatefulBuilder
_setState(() {
_passwordVisible = !_passwordVisible;
});
},
),
labelText: 'Password',
icon: const Padding(
padding: const EdgeInsets.only(top: 15.0),
child: const Icon(Icons.lock),
),
),
validator: (val) => val.length < 6 ? 'Password too short.' : null,
onSaved: (val) => _password = val,
obscureText: true,
);
}),
],
);
}
}
○ 只需簡單的 3 個步驟,您就可以按照密碼顯示/隱藏完成。
第一步:創建變量
bool _isHidden = true;
第 2 步:魔法步驟,使圖標可點擊並查看/隱藏密碼。
現在我將用 InkWell 包裹圖標,使其可點擊。 因此,當我們點擊它時,它會在真假之間切換模糊文本的參數。
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Theme.of(context).secondaryHeaderColor,
body: Center(
child: Container(
height: 55,
alignment: Alignment.center,
padding: EdgeInsets.fromLTRB(10, 10, 10, 0),
child: TextField(
obscureText: _isHidden,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Password',
suffix: InkWell(
onTap: _togglePasswordView, /// This is Magical Function
child: Icon(
_isHidden ? /// CHeck Show & Hide.
Icons.visibility :
Icons.visibility_off,
),
),
/*icon: Icon(
Icons.password_sharp,
color: Colors.black,
),*/
),
),
),
),
);
}
第 3 步:創建這個神奇的功能。
void _togglePasswordView() {
setState(() {
_isHidden = !_isHidden;
});
}
☻♥完成。
//Password
const TextField(
obscureText: true, //for hide Password
decoration: InputDecoration(
prefixIcon: Icon(Icons.lock_outline),
hintText: 'Password'),
),
TextFormFeild(
decoration:InputDecoration(
icon: _isSecurityIcon == true
? IconButton(
icon: Icon(Icons.visibility_off_outlined),
onPressed: () {
setState(() {
_isSecurityIcon = false;
});
},
)
: IconButton(
icon: Icon(Icons.visibility_outlined),
onPressed: () {
setState(
() {
_isSecurityIcon = true;
},
);
},
),
),
);```
我有更有用的解決方案。 您可以使用 Provider 並通過 Consumer Widget 收聽 TextFormField
晦澀的文本狀態.dart
import 'package:flutter/material.dart';
class ObscureTextState with ChangeNotifier {
bool _isTrue = true;
bool get isTrue => _isTrue;
get switchObsIcon {
return _isTrue ? Icon(Icons.visibility_off) : Icon(Icons.visibility);
}
void toggleObs() {
_isTrue = !_isTrue;
notifyListeners();
}
}
然后,您應該使用 TextFromField 所在的 Consumer 收聽該狀態。
Consumer<ObscureTextState>(
builder: (context, obs, child) {
return TextFormField(
controller: _passwordController,
validator: (value) {
if (value.isEmpty) {
return "Alan boş bırakılamaz!";
} else if (value.length < 6) {
return "Şifre en az 6 haneden oluşmalıdır.";
} else {
return null;
}
},
obscureText:
Provider.of<ObscureTextState>(context, listen: false)
.isTrue,
decoration: InputDecoration(
prefixIcon: Icon(Icons.lock),
suffixIcon: IconButton(
onPressed: () {
Provider.of<ObscureTextState>(context, listen: false)
.toggleObs();
},
icon: Provider.of<ObscureTextState>(context,
listen: false)
.switchObsIcon,
),
hintText: "Şifre",
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(20.0))),
);
},
),
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.