在我的项目中,我为密码创建了一个文本字段,并制定了一种显示和隐藏密码的方法。发生的事情是,当我按下图标显示文本时,键盘和光标消失了,我的意思是失去了焦点。
当我按下图标时,如何使它不失去焦点?谢谢
class ExampleLoginFocus extends StatefulWidget {
@override
_ExampleLoginFocusState createState() => _ExampleLoginFocusState();
}
class _ExampleLoginFocusState extends State<ExampleLoginFocus> {
FocusNode focusPass;
var pass = '';
bool passwordVisible;
@override
void initState() {
super.initState();
passwordVisible = true;
focusPass = FocusNode();
}
Widget password() {
return TextField(
obscureText: passwordVisible,
focusNode: focusPass,
decoration: InputDecoration(
suffixIcon: Padding(
padding: EdgeInsets.only(top: 20, bottom: 0),
child: IconButton(
icon: Icon(
passwordVisible ? Icons.visibility_off : Icons.visibility,
color: Theme.of(context).primaryColorDark,
),
onPressed: () {
setState(() {
passwordVisible = !passwordVisible;
});
},
)),
),
onChanged: (String tex) {
pass = tex;
print(pass);
},
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
child: password(),
),
);
}
}
答案 0 :(得分:1)
我无法测试您的代码,但是我有一个自定义文本字段小部件,该小部件允许使用属性来定义是通用文本字段还是密码文本字段,也许这对您有帮助
class DnetTextField extends StatefulWidget {
final String label;
final bool isPasswordField;
final TextEditingController controller;
final TextInputType textInputType;
final TextInputAction textInputAction;
final FormFieldValidator validator;
final IconData icon;
final Color color;
final Color errorColor;
final BuildContext context;
final FocusNode currentFocus;
final FocusNode nextFocus;
final bool autoValidate;
final double width;
final ValueChanged<String> onFieldSubmitted;
final List<TextInputFormatter> inputFormatters;
final TextCapitalization textCapitalization;
final int maxLength;
final bool focusable;
final String hint;
DnetTextField({
@required this.context,
@required this.label,
@required this.controller,
this.icon,
this.color,
this.errorColor,
this.textInputType = TextInputType.text,
this.textInputAction = TextInputAction.done,
this.validator,
this.isPasswordField = false,
this.currentFocus,
this.nextFocus,
this.onFieldSubmitted,
this.autoValidate = false,
this.width = 266,
this.inputFormatters,
this.textCapitalization = TextCapitalization.none,
this.maxLength = -1,
this.focusable = true,
this.hint,
});
@override
DnetTextFieldState createState() {
return DnetTextFieldState();
}
}
class DnetTextFieldState extends State<DnetTextField> {
bool hasErrors = false;
bool passwordVisible = false;
Color get currentColor => hasErrors ? widget.errorColor : widget.color;
IconData get currentIcon {
if (widget.isPasswordField) if (passwordVisible)
return Icons.visibility_off;
else
return Icons.visibility;
else
return widget.icon;
}
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
final border = OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(10.0)),
borderSide: BorderSide(color: currentColor),
);
final focusableTheme = widget.focusable
? Theme.of(context)
: Theme.of(
context,
).copyWith(
splashFactory: const NoSplashFactory(),
);
return Container(
width: widget.width,
height: 80,
child: Theme(
data: focusableTheme,
child: TextFormField(
inputFormatters: widget.inputFormatters,
style: TextStyle(color: currentColor),
controller: widget.controller,
keyboardType: widget.textInputType,
textInputAction: widget.textInputAction,
enableInteractiveSelection: widget.focusable,
focusNode:
widget.focusable ? widget.currentFocus : DnetDisabledFocusNode(),
decoration: InputDecoration(
hintText: widget.hint,
suffixIcon: getSuffixIcon(),
fillColor: currentColor,
labelText: widget.label,
labelStyle:
TextStyle(color: currentColor, fontStyle: FontStyle.italic),
focusedBorder: border,
enabledBorder: border,
border: border,
),
autovalidate: widget.autoValidate,
validator: (text) {
final validatorMessage =
widget.validator == null ? null : widget.validator(text);
setHasErrors(validatorMessage != null);
if (validatorMessage != null) return validatorMessage;
},
onFieldSubmitted: widget.onFieldSubmitted ??
(term) {
if (widget.nextFocus != null) {
FocusScope.of(context).requestFocus(widget.nextFocus);
}
},
obscureText: widget.isPasswordField && !passwordVisible,
textCapitalization: widget.textCapitalization,
maxLength: widget.maxLength != -1 ? widget.maxLength : null,
),
),
);
}
setHasErrors(bool errors) {
setState(() {
hasErrors = errors;
});
}
setPasswordVisible(bool visible) {
setState(() {
passwordVisible = visible;
});
}
GestureDetector getSuffixIcon() {
if (widget.icon != null || widget.isPasswordField) {
return GestureDetector(
child: Icon(
currentIcon,
color: currentColor,
),
onTap: () {
if (widget.isPasswordField) setPasswordVisible(!passwordVisible);
},
);
} else {
return null;
}
}
}