在Flutter中实现图形验证码可以通过以下步骤:
1. 使用自定义绘制(CustomPaint)
import 'package:flutter/material.dart';
class CaptchaWidget extends StatefulWidget {
@override
_CaptchaWidgetState createState() => _CaptchaWidgetState();
}
class _CaptchaWidgetState extends State<CaptchaWidget> {
String captchaText = '';
final TextEditingController _controller = TextEditingController();
@override
void initState() {
super.initState();
_generateCaptcha();
}
void _generateCaptcha() {
// 生成4位随机验证码(数字+字母)
const chars = 'ABCDEFGHJKLMNPQRSTUVWXYZ23456789';
final random = Random();
captchaText = String.fromCharCodes(
Iterable.generate(4, (_) => chars.codeUnitAt(random.nextInt(chars.length)))
);
setState(() {});
}
@override
Widget build(BuildContext context) {
return Column(
children: [
// 验证码显示区域
GestureDetector(
onTap: _generateCaptcha,
child: CustomPaint(
size: Size(120, 40),
painter: CaptchaPainter(captchaText),
),
),
SizedBox(height: 10),
// 输入框
TextField(
controller: _controller,
decoration: InputDecoration(
hintText: '请输入验证码',
border: OutlineInputBorder(),
),
),
SizedBox(height: 10),
ElevatedButton(
onPressed: _verifyCaptcha,
child: Text('验证'),
),
],
);
}
void _verifyCaptcha() {
if (_controller.text.toUpperCase() == captchaText) {
print('验证码正确');
} else {
print('验证码错误');
_generateCaptcha();
_controller.clear();
}
}
}
// 自定义绘制验证码
class CaptchaPainter extends CustomPainter {
final String text;
CaptchaPainter(this.text);
@override
void paint(Canvas canvas, Size size) {
final paint = Paint()
..color = Colors.grey[200]!
..style = PaintingStyle.fill;
// 绘制背景
canvas.drawRect(Rect.fromLTWH(0, 0, size.width, size.height), paint);
// 绘制干扰线
final random = Random();
for (int i = 0; i < 5; i++) {
final linePaint = Paint()
..color = Colors.grey
..strokeWidth = 1;
canvas.drawLine(
Offset(random.nextDouble() * size.width, random.nextDouble() * size.height),
Offset(random.nextDouble() * size.width, random.nextDouble() * size.height),
linePaint,
);
}
// 绘制文字
final textStyle = TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: _getRandomColor(),
);
for (int i = 0; i < text.length; i++) {
final textPainter = TextPainter(
text: TextSpan(text: text[i], style: textStyle),
textDirection: TextDirection.ltr,
)..layout();
// 随机位置和旋转
final offset = Offset(
i * 25 + random.nextDouble() * 5,
10 + random.nextDouble() * 10,
);
canvas.save();
canvas.translate(offset.dx + textPainter.width / 2, offset.dy + textPainter.height / 2);
canvas.rotate(random.nextDouble() * 0.5 - 0.25); // 随机旋转
textPainter.paint(canvas, Offset(-textPainter.width / 2, -textPainter.height / 2));
canvas.restore();
}
}
Color _getRandomColor() {
final random = Random();
return Color.fromRGBO(
random.nextInt(150),
random.nextInt(150),
random.nextInt(150),
1,
);
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) => true;
}
2. 使用第三方库(推荐)
dependencies:
flutter_captcha: ^0.0.1
import 'package:flutter_captcha/flutter_captcha.dart';
Captcha(
onConfirm: (value) {
print('验证码: $value');
},
onCancel: () {
print('取消验证');
},
)
主要实现要点:
- 随机生成验证码:使用数字和字母组合
- 添加干扰元素:干扰线、干扰点、颜色变化
- 文字变形:随机旋转、位置偏移
- 点击刷新:支持用户点击刷新验证码
- 验证逻辑:比对用户输入与生成的验证码
这种方法可以有效防止简单的机器识别,同时保持良好的用户体验。