Skip to content

Commit

Permalink
Merge pull request #4 from fluttercandies/modify-controller-code
Browse files Browse the repository at this point in the history
Modify controller code

- fix draw rect and controller problem.
- split controller.
- provider controller for page.
  • Loading branch information
CaiJingLong authored Apr 11, 2024
2 parents 755224a + 4e5c65a commit 3a64d53
Show file tree
Hide file tree
Showing 8 changed files with 104 additions and 75 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
## 0.3.0

- Remove an unused field.
- Add `BarcodeController` to control the barcode scanner to start, stop handle barcodes.

## 0.2.1

Expand Down
18 changes: 12 additions & 6 deletions example/lib/examples/change_qrcode_rect.dart
Original file line number Diff line number Diff line change
Expand Up @@ -42,27 +42,33 @@ class _CustomBarcodeOverlayExampleState
controller.start();
}
},
child: ValueListenableBuilder<bool>(
child: ValueListenableBuilder<BarcodeScanStatus>(
valueListenable: controller,
builder: (context, isScanning, child) {
return Icon(isScanning ? Icons.pause : Icons.play_arrow_rounded);
builder: (context, status, child) {
return Icon(
status.isScaning ? Icons.pause : Icons.play_arrow_rounded,
);
},
),
),
);
}

Widget _buildBarcodeRectItem(BuildContext context, Barcode barcode) {
Widget _buildBarcodeRectItem(
BuildContext context,
Barcode barcode, {
BarcodeController? controller,
}) {
return GestureDetector(
onTap: () async {
controller.stop();
controller?.stop();
await showDialog(
context: context,
builder: (context) => AlertDialog(
title: Text(barcode.rawValue ?? ''),
),
);
controller.start();
controller?.start();
},
child: Container(
decoration: BoxDecoration(
Expand Down
1 change: 1 addition & 0 deletions lib/scan_barcode.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export 'src/helper/ext.dart';

export 'src/core/config.dart';
export 'src/core/define.dart';
export 'src/core/controller.dart';

export 'package:camera/camera.dart';
export 'package:google_mlkit_barcode_scanning/google_mlkit_barcode_scanning.dart';
Expand Down
27 changes: 27 additions & 0 deletions lib/src/core/controller.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import 'package:flutter/foundation.dart';

enum BarcodeScanStatus {
init,
scanning,
stop,
}

extension BarcodeScanStatusExt on BarcodeScanStatus {
bool get isScaning => this == BarcodeScanStatus.scanning;
}

class BarcodeController extends ValueNotifier<BarcodeScanStatus> {
BarcodeController({
bool autoStart = true,
}) : super(autoStart ? BarcodeScanStatus.scanning : BarcodeScanStatus.init);

bool get isScanning => value == BarcodeScanStatus.scanning;

void start() {
value = BarcodeScanStatus.scanning;
}

void stop() {
value = BarcodeScanStatus.stop;
}
}
11 changes: 0 additions & 11 deletions lib/src/core/ui.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,3 @@ class UIConfig {

final BarcodeOverlayBuilder? barcodeOverlayBuilder;
}

Widget defaultBuildBarcodeRect(
BuildContext context,
BarcodeData barcodeData,
UIConfig config,
) {
return BarcodeRectWidget(
uiConfig: config,
barcodeData: barcodeData,
);
}
82 changes: 52 additions & 30 deletions lib/src/widget/barcode_rect.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,49 +3,56 @@ import 'package:scan_barcode/scan_barcode.dart';

typedef BarcodeOverlayBuilder = Widget Function(
BuildContext context,
Barcode barcode,
);
Barcode barcode, {
BarcodeController? controller,
});

class BarcodeRectWidget extends StatelessWidget {
const BarcodeRectWidget({
Key? key,
required this.barcodeData,
required this.uiConfig,
required this.controller,
}) : super(key: key);

final BarcodeData? barcodeData;
final UIConfig uiConfig;
final BarcodeController controller;

@override
Widget build(BuildContext context) {
return LayoutBuilder(
builder: (context, constraints) {
var data = barcodeData;
if (data == null) return Container();
final imageSize = data.image.metadata?.fixedSize;
if (imageSize == null) return Container();
final barcodeList = data.barcodeList;
if (barcodeList.isEmpty) return Container();
return ValueListenableBuilder(
valueListenable: controller,
builder: (context, value, child) => LayoutBuilder(
builder: (context, constraints) {
var data = barcodeData;
if (data == null) return Container();
final imageSize = data.image.metadata?.fixedSize;
if (imageSize == null) return Container();
final barcodeList = data.barcodeList;
if (barcodeList.isEmpty) return Container();

final width = imageSize.width;
final height = imageSize.height;
final width = imageSize.width;
final height = imageSize.height;

final scaleX = constraints.maxWidth / width;
final scaleY = constraints.maxHeight / height;
final scaleX = constraints.maxWidth / width;
final scaleY = constraints.maxHeight / height;

return Stack(
children: [
...barcodeList
.map((barcode) => _buildBarcode(
context,
barcode,
scaleX,
scaleY,
))
.whereType<Widget>()
],
);
},
return Stack(
children: [
...barcodeList
.map((barcode) => _buildBarcode(
context,
barcode,
scaleX,
scaleY,
controller,
))
.whereType<Widget>()
],
);
},
),
);
}

Expand All @@ -54,6 +61,7 @@ class BarcodeRectWidget extends StatelessWidget {
Barcode barcode,
double scaleX,
double scaleY,
BarcodeController controller,
) {
final rect = barcode.boundingBox;

Expand All @@ -69,15 +77,29 @@ class BarcodeRectWidget extends StatelessWidget {
top: top,
width: width,
height: height,
child: _buildItem(context, barcode),
child: _buildItem(context, barcode, controller),
);
}

Widget _buildItem(BuildContext context, Barcode barcode) {
Widget _buildItem(
BuildContext context,
Barcode barcode,
BarcodeController controller,
) {
final barcodeRectItemBuilder = uiConfig.barcodeOverlayBuilder;

if (barcodeRectItemBuilder != null) {
return barcodeRectItemBuilder(context, barcode);
return barcodeRectItemBuilder(
context,
barcode,
controller: controller,
);
}

if (!controller.isScanning) {
return Container();
}

return Container(
decoration: BoxDecoration(
border: Border.all(
Expand Down
37 changes: 9 additions & 28 deletions lib/src/widget/barcode_widget.dart
Original file line number Diff line number Diff line change
@@ -1,32 +1,6 @@
import 'package:flutter/material.dart';
import 'package:scan_barcode/scan_barcode.dart';

enum _BarcodeStatus {
init,
scanning,
stop,
}

class BarcodeController extends ValueNotifier<bool> {
BarcodeController({bool autoStart = true})
: _status = autoStart ? _BarcodeStatus.scanning : _BarcodeStatus.init,
super(false);

_BarcodeStatus _status;

bool get isScanning => _status == _BarcodeStatus.scanning;

void start() {
_status = _BarcodeStatus.scanning;
value = isScanning;
}

void stop() {
_status = _BarcodeStatus.stop;
value = isScanning;
}
}

class BarcodeWidget extends StatefulWidget {
const BarcodeWidget({
Key? key,
Expand Down Expand Up @@ -91,12 +65,18 @@ class _BarcodeWidgetState extends State<BarcodeWidget> {
builder: (BuildContext context, BarcodeData? data, Widget? child) {
return CameraImageWidget(
onImageCaptured: (CameraDescription camera, CameraImage image) async {
if (!controller.isScanning) return;
if (!controller.isScanning) {
barcodeData.value = null;
return;
}
return await handler.handleCameraImage(
camera,
image,
(data) async {
if (data.barcodeList.isEmpty) return;
if (data.barcodeList.isEmpty) {
barcodeData.value = null;
return;
}
if (controller.isScanning && widget.autoStop) {
controller.stop();
}
Expand All @@ -113,6 +93,7 @@ class _BarcodeWidgetState extends State<BarcodeWidget> {
child: BarcodeRectWidget(
barcodeData: data,
uiConfig: widget.scanValue.uiConfig,
controller: controller,
),
);
},
Expand Down
2 changes: 2 additions & 0 deletions lib/src/widget/qrcode_scan_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@ class BarcodeScanPage extends StatefulWidget {
required this.title,
required this.onHandleBarcodeList,
this.config,
this.controller,
}) : super(key: key);

final String title;
final OnHandleBarcodeList onHandleBarcodeList;
final ScanValue? config;
final BarcodeController? controller;

@override
State<BarcodeScanPage> createState() => _BarcodeScanPageState();
Expand Down

0 comments on commit 3a64d53

Please sign in to comment.