Reputation: 131
When typing text into a field with obscureText: true, each typed character is displayed briefly before being converted to a bullet. How do you stop the behavior?
Upvotes: 2
Views: 2315
Reputation: 11
To add to Sami's answer, if you want the ability to toggle password show and hide using a suffix icon while using ObscuringTextEditingController, you can initialise as follows:
var passwordControllerObscure = ObscuringTextEditingController();
var passwordController = TextEditingController();
Subsequently, the TextField would look like:
TextField(
controller: _showPassword ? passwordController : passwordControllerObscure,
decoration: InputDecoration(
suffixIcon: IconButton(
icon: Icon(
_showPassword
? Icons.visibility
: Icons.visibility_off,
color: colors.primary,
),
padding: const EdgeInsets.all(0),
onPressed: () {
if(_showPassword) {
//switch text between controllers on toggle
passwordControllerObscure.text = passwordController.text;
//set cursor to the end of the current controller on toggle
passwordControllerObscure.selection =
TextSelection.collapsed(offset: passwordControllerObscure.text.length);
} else {
passwordController.text = passwordControllerObscure.text;
passwordController.selection =
TextSelection.collapsed(offset: passwordController.text.length);
}
setState(() {
_showPassword = !_showPassword;
});
},
),
),
)
Upvotes: 1
Reputation: 1426
This was fixed on Web/Desktop, but there's no option to do it on Mobile. You can create a custom TextEditingController as suggested in this comment:
class ObscuringTextEditingController extends TextEditingController {
@override
TextSpan buildTextSpan({TextStyle style, bool withComposing}) {
var displayValue = '•' * value.text.length;
if (!value.composing.isValid || !withComposing) {
return TextSpan(style: style, text: displayValue);
}
final TextStyle composingStyle = style.merge(
const TextStyle(decoration: TextDecoration.underline),
);
return TextSpan(
style: style,
children: <TextSpan>[
TextSpan(text: value.composing.textBefore(displayValue)),
TextSpan(
style: composingStyle,
text: value.composing.textInside(displayValue),
),
TextSpan(text: value.composing.textAfter(displayValue)),
],
);
}
}
Remove obscureText
and use controller:
var passwordController = ObscuringTextEditingController();
TextField(
controller: passwordController,
decoration: const InputDecoration(hintText: 'Password'),
)
Upvotes: 6