目前我的密码TextFormField如下:
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: true,
),
我想要一个像交互一样的按钮,这会让密码变得可见和不可见。我可以在TextFormField
内进行吗?或者我必须制作一个Stack
小部件来获取我所需的UI。关于obscureText
真/假,条件如何?
答案 0 :(得分:21)
首先让小工具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"))
],
),
),
);
}
}
希望这有帮助!
答案 1 :(得分:14)
我已经按照@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;
});
},
),
),
);
希望这对某人有所帮助!
答案 2 :(得分:2)
如果您希望密码在与屏幕接触时可以看到,并且在您删除联系人后就将其隐藏起来,那么这是给您的
//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;
});
}
我也将其作为软件包发布在这里 Firebase CLI
以上代码的输出
答案 3 :(得分:2)
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();
});
},
),
],),),
),
);
}
}
答案 4 :(得分:1)
功劳归功于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;
});
},
),
答案 5 :(得分:1)
我是通过按住并释放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);
},
);
答案 6 :(得分:1)
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;
});
},
);
}
希望这会有所帮助!
答案 7 :(得分:1)
这是一个带有内置 Material Design 图标的简单示例:
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,
),
答案 8 :(得分:0)
感谢@Parikshit Chalke 的回答。然而,
如果您只想更新您的 setState
和 TextFormField
,那么 IconButton
是相当昂贵的调用。相反,将其包装在 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,
);
}),
],
);
}
}
答案 9 :(得分:-1)
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;
},
);
},
),
),
);```
答案 10 :(得分:-1)
我有更有用的解决方案。您可以使用 Provider 并通过 Consumer Widget 收听 TextFormField
obscure_text_state.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))),
);
},
),