实现Flutter离线验证码组件,小码农也有大梦想

final double width;

final double height;

final Color backgroundColor;

//回调

final ValueChanged verifyCallback;

const VerifyCode({Key key, this.vCodeNum=4, this.width=70, this.height=25, this.backgroundColor, this.verifyCallback}) : super(key: key);

@override

_VerifyCodeState createState() => _VerifyCodeState();

}

class _VerifyCodeState extends State {

String _rdStr = ‘’;

double maxWidth = 0.0;

Map _drawData;

String getRandomString(){

String code = “”;

for (var i = 0; i < widget.vCodeNum; i++) {

code = code + _charsAll[Random().nextInt(_charsAll.length)];

}

return code;

}

//随机生成绘图数据

Map getRandomData(String srt) {

// list

List list = srt.split(“”);

// X坐标

double x = 0.0;

// 最大字体大小

double maxFontSize = 25.0;

//将painter保存起来,先计算出位置

List mList = [];

for (String item in list) {

Color color = Color.fromARGB(255, Random().nextInt(255),

Random().nextInt(255), Random().nextInt(255));

int fontWeight = Random().nextInt(9);

TextSpan span = TextSpan(

text: item,

style: TextStyle(

color: color,

fontWeight: FontWeight.values[fontWeight],

fontSize: maxFontSize - Random().nextInt(10)));

TextPainter painter =

TextPainter(text: span, textDirection: TextDirection.ltr);

painter.layout();

double y =

Random().nextInt(widget.height.toInt()).toDouble() - painter.height;

if (y < 0) {

y = 0;

}

Map strMap = {“painter”: painter, “x”: x, “y”: y};

mList.add(strMap);

x += painter.width + 3;

}

double offsetX = (widget.width - x) / 2;

List dotData = [];

List lineData = [];

//绘制干扰点

for (var i = 0; i < widget.vCodeNum; i++) {

int r = Random().nextInt(255);

int g = Random().nextInt(255);

int b = Random().nextInt(255);

double x = Random().nextInt(widget.width.toInt() - 5).toDouble();

double y = Random().nextInt(widget.height.toInt() - 5).toDouble();

double dotWidth = Random().nextInt(6).toDouble();

Color color = Color.fromARGB(255, r, g, b);

Map dot = {“x”: x, “y”: y, “dotWidth”: dotWidth, “color”: color};

dotData.add(dot);

}

//绘制干扰线

for (var i = 0; i < widget.vCodeNum; i++) {

int r = Random().nextInt(255);

int g = Random().nextInt(255);

int b = Random().nextInt(255);

double x = Random().nextInt(widget.width.toInt() - 5).toDouble();

double y = Random().nextInt(widget.height.toInt() - 5).toDouble();

double lineLength = Random().nextInt(20).toDouble();

Color color = Color.fromARGB(255, r, g, b);

Map line = {“x”: x, “y”: y, “lineLength”: lineLength, “color”: color};

lineData.add(line);

}

Map checkCodeDrawData = {

“painterData”: mList,

“offsetX”: offsetX,

“dotData”: dotData,

“lineData”: lineData,

};

return checkCodeDrawData;

}

@override

void initState() {

// TODO: implement initState

_rdStr = getRandomString();

LogUtil.e(_rdStr);

_drawData = getRandomData(_rdStr);

//计算最大宽度做自适应

maxWidth = getTextSize(“8” * _rdStr.length,

TextStyle(fontWeight: FontWeight.values[8], fontSize: 25))

.width;

//数据回调

widget.verifyCallback(_rdStr);

super.initState();

}

@override

Widget build(BuildContext context) {

return Container(

color: widget.backgroundColor,

width: maxWidth > widget.width ? maxWidth : widget.width,

height: widget.height,

child: InkWell(

onTap: (){

setState(() {

_rdStr = getRandomString();

_drawData = getRandomData(_rdStr);

//数据回调

widget.verifyCallback(_rdStr);

});

},

child: CustomPaint(

painter: VerifyCodePainter(drawData: _drawData),

),

));

}

Size getTextSize(String text, TextStyle style) {

final TextPainter textPainter = TextPainter(

text: TextSpan(text: text, style: style),

maxLines: 1,

textDirection: TextDirection.ltr)

…layout(minWidth: 0, maxWidth: double.infinity);

return textPainter.size;

}

}

class VerifyCodePainter extends CustomPainter {

final Map drawData;

VerifyCodePainter({

@required this.drawData,

});

Paint _paint = new Paint()

…color = Colors.grey

…strokeCap = StrokeCap.square

…isAntiAlias = true

…strokeWidth = 1.0

…style = PaintingStyle.fill;

@override

void paint(Canvas canvas, Size size) {

List mList = drawData[“painterData”];

double offsetX = drawData[“offsetX”];

//居中显示移动画布

canvas.translate(offsetX, 0);

//从Map中取出值,直接绘制

for (var item in mList) {

TextPainter painter = item[“painter”];

double x = item[“x”];

double y = item[“y”];

painter.paint(

canvas,

Offset(x, y),

);

}

// //将画布平移回去

canvas.translate(-offsetX, 0);

List dotData = drawData[“dotData”];

for (var item in dotData) {

double x = item[“x”];

double y = item[“y”];

double dotWidth = item[“dotWidth”];

Color color = item[“color”];

_paint.color = color;

canvas.drawOval(Rect.fromLTWH(x, y, dotWidth, dotWidth), _paint);

}

List lineData = drawData[“lineData”];

for (var item in lineData) {

double x = item[“x”];

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级安卓工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Android移动开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Android)
img

最后

其实Android开发的知识点就那么多,面试问来问去还是那么点东西。所以面试没有其他的诀窍,只看你对这些知识点准备的充分程度。so,出去面试时先看看自己复习到了哪个阶段就好。

以上分享【我的阿里P7移动开发架构师学习笔记】七大模块整套学习资料均免费分享,需要的小伙伴,我已经上传到石墨文档了,大家自取就可以了。白嫖可以,别忘了给我点个关注哈。

当然我也为你们整理好了百度、阿里、腾讯、字节跳动等等互联网超级大厂的历年面试真题集锦。这也是我这些年来养成的习惯,一定要学会把好的东西,归纳整理,然后系统的消化吸收,这样才能极大的提高学习效率和成长进阶。碎片、零散化的东西,我觉得最没有价值的。就好比你给我一张扑克牌,我只会觉得它是一张废纸,但如果你给我一副扑克牌,它便有了它的价值。这和我们收集资料就要收集那些系统化的,是一个道理。

如果你需要,我把他放在GitHub了,无偿分享的。

【Android架构视频+BATJ面试专题PDF+学习笔记】

网上学习 Android的资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。希望这份系统化的技术体系对大家有一个方向参考。
跳动等等互联网超级大厂的历年面试真题集锦。这也是我这些年来养成的习惯,一定要学会把好的东西,归纳整理,然后系统的消化吸收,这样才能极大的提高学习效率和成长进阶。碎片、零散化的东西,我觉得最没有价值的。就好比你给我一张扑克牌,我只会觉得它是一张废纸,但如果你给我一副扑克牌,它便有了它的价值。这和我们收集资料就要收集那些系统化的,是一个道理。

如果你需要,我把他放在GitHub了,无偿分享的。

【Android架构视频+BATJ面试专题PDF+学习笔记】

[外链图片转存中…(img-Uze7sqKv-1710697380077)]

网上学习 Android的资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。希望这份系统化的技术体系对大家有一个方向参考。

  • 23
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值