flutter_jc_printer_plugin/example/lib/main.dart
2023-11-28 23:44:09 +08:00

260 lines
6.7 KiB
Dart

import 'dart:async';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_reactive_ble/flutter_reactive_ble.dart';
import 'package:jc_printer/jc_printer.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(
home: HomePage(),
);
}
}
class HomePage extends StatefulWidget {
const HomePage({super.key});
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
final TextEditingController _labelWidthInput = TextEditingController();
final TextEditingController _labelHeightInput = TextEditingController();
final TextEditingController _countInput = TextEditingController();
final _printer = JcPrinter();
ConnectState _connectState = ConnectState.none;
StreamSubscription<ConnectState>? _connectStateSubs;
StreamSubscription<int>? _printingCountSubs;
StreamSubscription<Map<String, String>>? _errorInfoSubs;
DiscoveredDevice? _device;
String get _title {
switch (_connectState) {
case ConnectState.connecting:
return '连接中';
case ConnectState.connected:
return _device?.name ?? '已连接';
case ConnectState.none:
return '未连接';
}
}
@override
void initState() {
_labelWidthInput.text = '40';
_labelHeightInput.text = '30';
_countInput.text = '1';
_connectStateSubs = _printer.connectStateStream.listen(
_connectStateListener,
);
_printingCountSubs = _printer.printingCountStream.listen(
_printingCountListener,
);
_errorInfoSubs = _printer.errorInfoStream.listen(
_errorInfoListener,
);
super.initState();
}
@override
void dispose() {
_labelWidthInput.dispose();
_labelHeightInput.dispose();
_countInput.dispose();
_connectStateSubs?.cancel();
_printingCountSubs?.cancel();
_errorInfoSubs?.cancel();
super.dispose();
}
void _connectStateListener(ConnectState state) {
setState(() {
_connectState = state;
});
}
void _printingCountListener(int count) {
print(count);
}
void _errorInfoListener(Map<String, String> error) {
debugPrint(error.toString());
}
void _connect() {
_printer.connect(_device!.name);
}
void _startPrint() async {
final count = int.tryParse(_countInput.value.text) ?? 0;
_printer.setTotalPrints(count);
await _printer.startPrint();
final data = await _getLabelData();
await _printer.commit(data: data, count: count);
}
Future<String> _getLabelData() async {
final labelWidth = double.tryParse(_labelWidthInput.value.text) ?? 0;
final labelHeight = double.tryParse(_labelHeightInput.value.text) ?? 0;
await _printer.initDrawingBoard(
width: labelWidth,
height: labelHeight,
font: 'SourceHanSans-Regular.ttc',
);
await _printer.drawLabelText(
width: labelWidth,
height: 7,
content: '打印测试',
fontSize: 7,
);
await _printer.drawLabelBarcode(
width: 30,
x: 5,
y: 7,
height: 18,
text: '123456',
fontSize: 4,
textHeight: 4,
);
return _printer.getLabelData();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: _connectState == ConnectState.connecting
? const CupertinoActivityIndicator()
: Text(_title),
actions: [
TextButton(
onPressed: () async {
if (_connectState == ConnectState.connected) {
_printer.disconnect();
return;
}
final result = await showDialog<DiscoveredDevice>(
context: context,
builder: (BuildContext context) => _DevicesDialog(
onTap: Navigator.of(context).pop,
),
);
if (result == null) return;
_device = result;
_connect();
},
child: Text(
_connectState == ConnectState.connected ? '断开' : '连接设备',
style: const TextStyle(color: Colors.white),
),
),
],
),
body: SingleChildScrollView(
padding: const EdgeInsets.all(20),
child: Center(
child: Column(
children: [
TextField(
controller: _labelWidthInput,
decoration: const InputDecoration(label: Text('标签宽度')),
),
TextField(
controller: _labelHeightInput,
decoration: const InputDecoration(label: Text('标签高度')),
),
TextField(
controller: _countInput,
decoration: const InputDecoration(label: Text('每份数量')),
),
const SizedBox(height: 20),
ElevatedButton(
onPressed: _startPrint,
child: const Text('开始打印'),
),
],
),
),
),
);
}
}
class _DevicesDialog extends StatefulWidget {
final void Function(DiscoveredDevice device)? onTap;
const _DevicesDialog({
Key? key,
this.onTap,
}) : super(key: key);
@override
State<_DevicesDialog> createState() => _DevicesDialogState();
}
class _DevicesDialogState extends State<_DevicesDialog> {
final _ble = FlutterReactiveBle();
final List<DiscoveredDevice> _devices = [];
StreamSubscription<DiscoveredDevice>? _scanSubs;
@override
void initState() {
_scanSubs = _ble.scanForDevices(
withServices: [],
).listen(_scanListener);
super.initState();
}
@override
void dispose() {
_scanSubs?.cancel();
super.dispose();
}
void _scanListener(DiscoveredDevice device) {
if (device.name.isEmpty) return;
if (device.connectable != Connectable.available) return;
final index = _devices.indexWhere(
(element) => element.id == device.id,
);
if (index > -1) {
_devices[index] = device;
} else {
_devices.add(device);
}
if (mounted) setState(() {});
}
@override
Widget build(BuildContext context) {
return Dialog(
child: ConstrainedBox(
constraints: const BoxConstraints(maxHeight: 400),
child: ListView.separated(
itemBuilder: (BuildContext context, int index) {
final item = _devices[index];
return ListTile(
title: Text(item.name),
onTap: () => widget.onTap?.call(item),
);
},
itemCount: _devices.length,
separatorBuilder: (_, __) => const Divider(),
),
),
);
}
}