123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351 |
- part of fqreader;
- class ScanView extends StatefulWidget {
- /// 扫描事件
- final ScanEvent onScan;
- /// 扫描区域位置大小
- final Rect? scanRect;
- /// 扫描区域大小
- final Size? scanSize;
- /// ScanView控件大小
- final Size viewSize;
- /// 扫描框的位置(位于图片)
- final Alignment scanAilgn;
- /// view的位置(位于图片)
- final Alignment viewAilgn;
- /// 屏幕分辨率
- final double devicePixelRatio;
- final Color? maskColor;
- /// 是否立即扫描
- final bool autoScan;
- /// 是否连续扫描
- final bool continuityScan;
- /// 连续扫描间隔
- final Duration scanInterval;
- /// 扫描的条码类型
- final List<ScanType> scanType;
- const ScanView(
- {Key? key,
- required this.onScan,
- required this.viewSize,
- this.scanRect,
- this.scanSize,
- this.scanAilgn = Alignment.topLeft,
- this.viewAilgn = Alignment.topLeft,
- required this.devicePixelRatio,
- this.maskColor,
- this.scanType = const [ScanType.ALL],
- this.autoScan = true,
- this.continuityScan = false,
- this.scanInterval = const Duration(milliseconds: 500)})
- : assert(scanSize != null || scanRect != null),
- assert(!(scanSize != null && scanRect != null)),
- super(key: key);
- @override
- State<StatefulWidget> createState() => ScanViewState();
- }
- class ScanViewState extends State<ScanView> {
- int? _textureId;
- StreamSubscription? _readySubscription;
- Size? _cameraSize;
- double? _cameraPixelRatio;
- @override
- void initState() {
- // TODO: implement initState
- super.initState();
- if (widget.autoScan) {
- this.startScan();
- }
- }
- @override
- Widget build(BuildContext context) {
- return _textureId != null
- ? new _ScanViewTexture(
- textureId: _textureId!,
- cameraSize: _cameraSize!,
- scanRect: widget.scanRect ??
- _getViewRect(_cameraSize!, widget.scanSize!, widget.scanAilgn),
- maskColor: widget.maskColor,
- viewRect:
- _getViewRect(_cameraSize!, widget.viewSize, widget.viewAilgn),
- )
- : new SizedBox(
- width: widget.viewSize.width, height: widget.viewSize.height);
- }
- Rect _getViewRect(Size cameraSize, Size viewSize, Alignment alignment) {
- var offset = (cameraSize - viewSize) as Offset;
- return alignment.alongOffset(offset) & viewSize;
- }
- Size _cameraToViewSize(Size cameraSize) {
- return Size(cameraSize.width * _cameraPixelRatio!,
- cameraSize.height * _cameraPixelRatio!);
- }
- Rect _viewToCameraRect(Rect viewSize) {
- return Rect.fromLTWH(
- viewSize.left / _cameraPixelRatio!,
- viewSize.top / _cameraPixelRatio!,
- viewSize.width / _cameraPixelRatio!,
- viewSize.height / _cameraPixelRatio!);
- }
- @override
- void dispose() {
- // TODO: implement deactivate
- super.dispose();
- this.release();
- }
- /**
- * 开始扫描
- */
- Future startScan() async {
- if (this._textureId == null) {
- var initResult = await Fqreader._initView(
- devicePixelRatio: widget.devicePixelRatio,
- scanType: widget.scanType);
- _cameraPixelRatio = widget.viewSize.width / initResult.cameraSize.width;
- _cameraSize = _cameraToViewSize(initResult.cameraSize);
- _textureId = initResult.textureID;
- Rect scanRect = widget.scanRect ??
- _getViewRect(_cameraSize!, widget.scanSize!, widget.scanAilgn);
- var left = scanRect.left < 0.0 ? 0.0 : scanRect.left;
- var top = scanRect.top < 0.0 ? 0.0 : scanRect.top;
- var width = (left + scanRect.width > _cameraSize!.width) ? _cameraSize!.width - left : scanRect.width;
- var height = (top + scanRect.height > _cameraSize!.height) ? _cameraSize!.height - top : scanRect.height;
- scanRect = Rect.fromLTWH(
- left,
- top,
- width,
- height); // 确保不超出界限
- scanRect = _viewToCameraRect(scanRect);
- Fqreader._setScanRect(scanRect, widget.devicePixelRatio);
- _readySubscription = new EventChannel('fqreader/scanEvents$_textureId')
- .receiveBroadcastStream()
- .listen(_listener);
- setState(() {});
- }
- await Fqreader._startScan();
- }
- /**
- * 暂停扫描
- */
- Future stopScan() async {
- await Fqreader._stopScan();
- }
- /**
- * 开灯
- */
- Future turnOn() async {
- await Fqreader._turnOn();
- }
- /**
- * 关灯
- */
- Future turnOff() async {
- await Fqreader._turnOff();
- }
- Future release() async {
- if (this._textureId != null) {
- this._textureId = null;
- try {
- setState(() {});
- } catch (_) {}
- await _readySubscription!.cancel();
- await Fqreader._release();
- }
- }
- void _listener(dynamic value) {
- if (widget != null) {
- if (!widget.continuityScan) //是否连续扫描
- {
- Fqreader._stopScan();
- }
- var result = ScanResult(
- scanType: _parseScanType(value['scanType']),
- data: value['data'],
- );
- widget.onScan(result).then((result) {
- if (widget.continuityScan && result) {
- Future.delayed(widget.scanInterval, () {
- Fqreader._startScan();
- });
- } else {
- Fqreader._stopScan();
- }
- });
- }
- }
- }
- class _ScanViewTexture extends LeafRenderObjectWidget {
- final Size cameraSize;
- final Rect viewRect;
- final Rect? scanRect;
- final Color? maskColor;
- /// Creates a widget backed by the texture identified by [textureId].
- const _ScanViewTexture(
- {Key? key,
- required this.cameraSize,
- required this.viewRect,
- required this.textureId,
- this.scanRect,
- this.maskColor})
- : super(key: key);
- /// The identity of the backend texture.
- final int textureId;
- @override
- _ScanViewTextureBox createRenderObject(BuildContext context) =>
- _ScanViewTextureBox(
- textureId: textureId, cameraSize: cameraSize, viewRect: viewRect, maskColor: maskColor,scanRect: scanRect);
- @override
- void updateRenderObject(
- BuildContext context, _ScanViewTextureBox renderObject) {
- renderObject.textureId = textureId;
- renderObject.maskColor = maskColor;
- renderObject.cameraSize = cameraSize;
- renderObject.viewRect = viewRect;
- renderObject.scanRect = scanRect;
- }
- }
- class _ScanViewTextureBox extends RenderBox {
- /// Creates a box backed by the texture identified by [textureId].
- _ScanViewTextureBox(
- {required int textureId,
- required Size cameraSize,
- required Rect viewRect,
- required Rect? scanRect,
- Color? maskColor})
- : _textureId = textureId,
- _cameraSize = cameraSize,
- _viewRect = viewRect,
- _scanRect = scanRect,
- _maskColor = maskColor;
- /// The identity of the backend texture.
- int get textureId => _textureId;
- int _textureId;
- set textureId(int value) {
- if (value != _textureId) {
- _textureId = value;
- markNeedsPaint();
- }
- }
- Size get cameraSize => _cameraSize;
- Size _cameraSize;
- set cameraSize(Size value) {
- if (value != _cameraSize) {
- _cameraSize = value;
- markNeedsPaint();
- }
- }
- Rect get viewRect => _viewRect;
- Rect _viewRect;
- set viewRect(Rect value) {
- if (value != _viewRect) {
- _viewRect = value;
- markNeedsPaint();
- }
- }
- Rect? get scanRect => _scanRect;
- Rect? _scanRect;
- set scanRect(Rect? value) {
- if (value != _scanRect) {
- _scanRect = value;
- markNeedsPaint();
- }
- }
- Color? get maskColor => _maskColor;
- Color? _maskColor;
- set maskColor(Color? value) {
- if (value != _maskColor) {
- _maskColor = value;
- markNeedsPaint();
- }
- }
- @override
- bool get sizedByParent => true;
- @override
- bool get alwaysNeedsCompositing => true;
- @override
- bool get isRepaintBoundary => true;
- @override
- void performResize() {
- size = viewRect.size;
- }
- @override
- bool hitTestSelf(Offset position) => true;
- @override
- void paint(PaintingContext context, Offset offset) {
- if (_textureId == null) return;
- var cameraSize = Size(viewRect.width,
- viewRect.width * (_cameraSize.height / _cameraSize.width));
- context.pushClipRect(needsCompositing, offset,
- Rect.fromLTWH(0, 0, viewRect.width, viewRect.height),
- (PaintingContext context, Offset offset) {
- context.addLayer(TextureLayer(
- rect: Rect.fromLTWH(offset.dx - viewRect.left, offset.dy - viewRect.top,
- cameraSize.width, cameraSize.height),
- textureId: _textureId,
- ));
- if (maskColor != null) {
- Paint paint = Paint()..color = maskColor!;
- context.canvas
- .drawRect(Rect.fromLTWH(0, 0, viewRect.width, scanRect!.top), paint);
- context.canvas.drawRect(
- Rect.fromLTWH(0, scanRect!.top, scanRect!.left, scanRect!.height),
- paint);
- context.canvas.drawRect(
- Rect.fromLTWH(0, scanRect!.bottom, viewRect.width,
- viewRect.height - scanRect!.bottom),
- paint);
- context.canvas.drawRect(
- Rect.fromLTWH(scanRect!.right, scanRect!.top,
- viewRect.width - scanRect!.right, scanRect!.height),
- paint);
- }
- });
- }
- }
|