写点什么

实现 Flutter 离线验证码组件,跳槽面试大厂被拒

用户头像
Android架构
关注
发布于: 刚刚

@override


bool shouldRepaint(CustomPainter oldDelegate) {


return this != oldDelegate;


}


}


这样整体的工作就完成的差不多了,现在就差把整个组件实现起来;剩下的我就把完整的代码附上把毕竟摸鱼的人有什么坏心眼呢?


文件名:verifycode_widget.dart 欢迎自取有需要的自己改吧! 再次还是感谢【尤先森】大佬。hb_check_code: ^0.0.2(https://pub.flutter-io.cn/packages/hb_check_code


import 'dart:math';


import 'package:flutter/material.dart';


import 'package:flutter_tyyjk/util/log_utils.dart';


const _charsAll = ['1', '2', '3', '4', '5', '6',


'7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'j',


'k', 'm', 'n', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',


'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J',


'K', 'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',


'X', 'Y', 'Z'];


class VerifyCode extends StatefulWidget {


final int vCodeNum;


final double width;


final double height;


final Color backgroundColor;


//回调


final ValueChanged<String> 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<VerifyCode> {


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: maxW


《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
浏览器打开:qq.cn.hn/FTe 免费领取
复制代码


idth > 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"];


double y = item["y"];


double lineLength = item["lineLength"];


Color color = item["color"];


_paint.color = color;


canvas.drawLine(Offset(x,y),Offset(x+lineLength,y), _paint);


}


}


@override

用户头像

Android架构

关注

还未添加个人签名 2021.10.31 加入

还未添加个人简介

评论

发布
暂无评论
实现Flutter离线验证码组件,跳槽面试大厂被拒