Flutter中为带obscureText属性的TextField添加密码显示/隐藏图标
实现多密码输入框的显示/隐藏切换功能
核心思路
- 为每个密码输入框单独维护布尔状态变量,控制
obscureText的取值(隐藏时obscureText=true,显示时obscureText=false) - 在TextField的
suffixIcon属性中添加可点击图标,点击时切换对应状态变量 - 根据状态变量切换显示的图标(
Icons.visibility表示可见,Icons.visibility_off表示隐藏)
完整示例代码
基础实现(多个独立密码框)
import 'package:flutter/material.dart'; class PasswordInputPage extends StatefulWidget { const PasswordInputPage({super.key}); @override State<PasswordInputPage> createState() => _PasswordInputPageState(); } class _PasswordInputPageState extends State<PasswordInputPage> { // 每个密码框对应独立的状态变量 bool _isPwdVisible1 = false; bool _isPwdVisible2 = false; final _pwdController1 = TextEditingController(); final _pwdController2 = TextEditingController(); @override void dispose() { _pwdController1.dispose(); _pwdController2.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('密码输入示例')), body: Padding( padding: const EdgeInsets.all(16.0), child: Column( children: [ TextField( controller: _pwdController1, obscureText: !_isPwdVisible1, decoration: InputDecoration( labelText: '登录密码', border: const OutlineInputBorder(), suffixIcon: IconButton( icon: Icon( _isPwdVisible1 ? Icons.visibility : Icons.visibility_off, color: Theme.of(context).primaryColor, ), onPressed: () => setState(() => _isPwdVisible1 = !_isPwdVisible1), ), ), ), const SizedBox(height: 16), TextField( controller: _pwdController2, obscureText: !_isPwdVisible2, decoration: InputDecoration( labelText: '确认密码', border: const OutlineInputBorder(), suffixIcon: IconButton( icon: Icon( _isPwdVisible2 ? Icons.visibility : Icons.visibility_off, color: Theme.of(context).primaryColor, ), onPressed: () => setState(() => _isPwdVisible2 = !_isPwdVisible2), ), ), ), ], ), ), ); } }
优化方案:封装自定义组件
如果项目中有大量密码输入框,建议封装成可复用组件,减少重复代码:
// 自定义密码输入组件 class PasswordTextField extends StatefulWidget { final String labelText; final TextEditingController controller; final ValueChanged<String>? onChanged; const PasswordTextField({ super.key, required this.labelText, required this.controller, this.onChanged, }); @override State<PasswordTextField> createState() => _PasswordTextFieldState(); } class _PasswordTextFieldState extends State<PasswordTextField> { bool _isPwdVisible = false; @override Widget build(BuildContext context) { return TextField( controller: widget.controller, onChanged: widget.onChanged, obscureText: !_isPwdVisible, decoration: InputDecoration( labelText: widget.labelText, border: const OutlineInputBorder(), suffixIcon: IconButton( icon: Icon( _isPwdVisible ? Icons.visibility : Icons.visibility_off, color: Theme.of(context).primaryColor, ), onPressed: () => setState(() => _isPwdVisible = !_isPwdVisible), ), ), ); } }
组件使用示例
// 在页面中调用自定义组件 Column( children: [ PasswordTextField( labelText: '登录密码', controller: _pwdController1, ), const SizedBox(height: 16), PasswordTextField( labelText: '支付密码', controller: _pwdController2, ), const SizedBox(height: 16), PasswordTextField( labelText: '验证密码', controller: _pwdController3, ), ], )
内容的提问来源于stack exchange,提问作者Iniisking
相关产品推荐
相关产品推荐

