3.密码长度大于8,且同时包含数字、字母和特殊字符,则认为是强密码。
const StreamBuilder({ super.key, this.initialData, super.stream, required this.builder, });这是一个泛型类,因此可以接收任何类型的数据,比如我们自定义的业务对象。其中各个参数说明如下:
final StreamController<String> _inputController = StreamController<String>(); // ... @override Widget build(BuildContext context) { //堆代码 duidaima.com TextField( keyboardType: TextInputType.visiblePassword, onChanged: (text) { _inputController.add(text); }, decoration: const InputDecoration(labelText: '请输入密码'), ), //... StreamBuilder<String>( stream: _inputController.stream, initialData: '', builder: (context, snapshot) { final passwordStrength = calculateStrength(snapshot.data!); return PasswordStrengthIndicator( passwordStrength: passwordStrength, lineHeight: 4.0); }, ), }PasswordStrengthIndicator是自定义的密码指示器,实现的话是一个 Row 组件,通过 Flex 组件保持三段线(Container) 等宽,代码比较简单,如下所示。其中PasswordStrength是一个枚举,有 weak、medium 和 strong 三个值,分别对应弱密码、中等强度密码和强密码。
class PasswordStrengthIndicator extends StatelessWidget { final PasswordStrength passwordStrength; final double lineHeight; const PasswordStrengthIndicator( {super.key, required this.passwordStrength, required this.lineHeight}); final _strengthGapWidth = 8.0; @override Widget build(BuildContext context) { var passwordIndicator = PasswordIndicator(passwordStrength: passwordStrength); return Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Flexible( flex: 1, child: Container( height: lineHeight, color: passwordIndicator.lineColors[0], ), ), SizedBox(width: _strengthGapWidth), Flexible( flex: 1, child: Container( height: lineHeight, color: passwordIndicator.lineColors[1], ), ), SizedBox(width: _strengthGapWidth), Flexible( flex: 1, child: Container( height: lineHeight, color: passwordIndicator.lineColors[2], ), ), SizedBox(width: _strengthGapWidth), Text( passwordIndicator.strengthText, style: TextStyle( fontWeight: FontWeight.bold, color: passwordIndicator.strengthTextColor, ), ), ], ); } }PasswordIndicator是一个自定义的实体类,主要是简化密码强度指示器的代码,将组件显示所需要的数据全部封装到这个实体类中,包括线段显示的颜色,密码强弱指示文字内容和文字颜色。代码如下:
class PasswordIndicator { final PasswordStrength passwordStrength; late List<Color> _lineColors; late String _strengthText; late Color _strengthTextColor; PasswordIndicator({required this.passwordStrength}) { switch (passwordStrength) { case PasswordStrength.weak: _lineColors = const [ Color(0xFFCCCCCC), Color(0xFFCCCCCC), Color(0xFFCCCCCC) ]; _strengthText = '弱'; _strengthTextColor = Colors.red; break; case PasswordStrength.medium: _lineColors = const [ Color(0xFF00A52B), Color(0xFF00A52B), Color(0xFFCCCCCC) ]; _strengthText = '中等'; _strengthTextColor = Colors.orange; break; default: _lineColors = const [ Color(0xFF00A52B), Color(0xFF00A52B), Color(0xFF00A52B) ]; _strengthText = '强'; _strengthTextColor = const Color(0xFF00A52B); break; } } get lineColors => _lineColors; get strengthText => _strengthText; get strengthTextColor => _strengthTextColor; }最后是密码强度校验逻辑,这个使用方法calculateStrength实现,其实这个也可以作为一个工具方法使用。方法定义如下,主要是通过正则来判断密码的强弱。
PasswordStrength calculateStrength(String password) { if (password.length >= 8) { bool hasDigit = false; bool hasLetter = false; bool hasSpecial = false; for (var char in password.split('')) { if (RegExp(r'[0-9]').hasMatch(char)) { hasDigit = true; } else if (RegExp(r'[A-Za-z]').hasMatch(char)) { hasLetter = true; } else { hasSpecial = true; } } if (hasDigit && hasLetter && hasSpecial) { return PasswordStrength.strong; } else if ((hasDigit && hasLetter) || (hasDigit && hasSpecial) || (hasLetter && hasSpecial)) { return PasswordStrength.medium; } } return PasswordStrength.weak; } }