flutter_bixolon_printer 0.0.1
flutter_bixolon_printer: ^0.0.1 copied to clipboard
A Flutter plugin for connecting to and printing with Bixolon thermal printers. Supports device discovery, connection management, text/image/barcode printing, and international character sets.
example/lib/main.dart
import 'package:flutter/material.dart';
import 'package:flutter_bixolon_printer/flutter_bixolon_printer.dart';
import 'package:permission_handler/permission_handler.dart';
import 'dart:async';
void main() {
runApp(const PrinterExampleApp());
}
class PrinterExampleApp extends StatefulWidget {
const PrinterExampleApp({Key? key}) : super(key: key);
@override
State<PrinterExampleApp> createState() => _PrinterExampleAppState();
}
class _PrinterExampleAppState extends State<PrinterExampleApp> {
bool _isConnected = false;
List<PrinterDevice> _devices = [];
PrinterDevice? _selectedDevice;
String _status = "Ready";
bool _isLoading = false;
@override
void initState() {
super.initState();
_requestPermissions();
}
Future<void> _requestPermissions() async {
if (Theme.of(context).platform == TargetPlatform.android) {
await [
Permission.bluetooth,
Permission.bluetoothConnect,
Permission.bluetoothScan,
Permission.location,
Permission.storage,
].request();
}
}
Future<void> _scanPrinters() async {
setState(() {
_isLoading = true;
_status = "Scanning for printers...";
_devices = [];
});
try {
// Scan for Bluetooth printers
final bluetoothPrinters =
await FlutterBixolonPrinter.scanBluetoothPrinters();
// Scan for network printers
final networkPrinters = await FlutterBixolonPrinter.scanNetworkPrinters();
setState(() {
_devices = [...bluetoothPrinters, ...networkPrinters];
_status = "Found ${_devices.length} printers";
_isLoading = false;
});
} catch (e) {
setState(() {
_status = "Error scanning: $e";
_isLoading = false;
});
}
}
Future<void> _connectPrinter() async {
if (_selectedDevice == null) {
setState(() {
_status = "No printer selected";
});
return;
}
setState(() {
_isLoading = true;
_status = "Connecting to ${_selectedDevice!.name}...";
});
try {
// Initialize the printer
final initialized = await FlutterBixolonPrinter.initialize(
deviceName: _selectedDevice!.name,
address: _selectedDevice!.address,
connectionType: _selectedDevice!.connectionType,
model: _getModelFromName(_selectedDevice!.name),
);
if (!initialized) {
setState(() {
_status = "Failed to initialize printer";
_isLoading = false;
});
return;
}
// Connect to the printer
final connected = await FlutterBixolonPrinter.connect(timeout: 5000);
setState(() {
_isConnected = connected;
_status = connected
? "Connected to ${_selectedDevice!.name}"
: "Failed to connect";
_isLoading = false;
});
} catch (e) {
setState(() {
_status = "Connection error: $e";
_isLoading = false;
});
}
}
Future<void> _disconnectPrinter() async {
setState(() {
_isLoading = true;
_status = "Disconnecting...";
});
try {
final disconnected = await FlutterBixolonPrinter.disconnect();
setState(() {
_isConnected = !disconnected;
_status = disconnected ? "Disconnected" : "Failed to disconnect";
_isLoading = false;
});
} catch (e) {
setState(() {
_status = "Disconnection error: $e";
_isLoading = false;
});
}
}
Future<void> _printTextSample() async {
if (!_isConnected) {
_showNotConnectedMessage();
return;
}
setState(() {
_isLoading = true;
_status = "Printing text sample...";
});
try {
await FlutterBixolonPrinter.printCenteredText(
text: "TEXT PRINTING SAMPLE",
fontSize: 28,
fontWeight: FontWeight.bold,
);
await FlutterBixolonPrinter.printBlankLines(1);
await FlutterBixolonPrinter.printText("Regular text printing\n");
await FlutterBixolonPrinter.printText("More regular text\n");
await FlutterBixolonPrinter.printBlankLines(1);
await FlutterBixolonPrinter.printCenteredText(
text: "Centered Text Example",
fontSize: 22,
);
await FlutterBixolonPrinter.printBlankLines(1);
await FlutterBixolonPrinter.printFormattedText(
columns: [
const TextColumn(text: 'Left', x: 0),
const TextColumn(text: 'Center', x: 288, align: TextAlign.center),
const TextColumn(text: 'Right', x: 576, align: TextAlign.right),
],
);
await FlutterBixolonPrinter.cutPaper();
setState(() {
_status = "Text sample printed";
_isLoading = false;
});
} catch (e) {
setState(() {
_status = "Printing error: $e";
_isLoading = false;
});
}
}
Future<void> _printBarcodeSample() async {
if (!_isConnected) {
_showNotConnectedMessage();
return;
}
setState(() {
_isLoading = true;
_status = "Printing barcode sample...";
});
try {
await FlutterBixolonPrinter.printCenteredText(
text: "BARCODE SAMPLES",
fontSize: 28,
fontWeight: FontWeight.bold,
);
await FlutterBixolonPrinter.printBlankLines(1);
// Print Code 128 barcode
await FlutterBixolonPrinter.printCenteredText(
text: "CODE 128",
fontSize: 22,
);
await FlutterBixolonPrinter.printBarcode(
"1234567890",
BarcodeType.code128,
height: 100,
width: 2,
alignment: Alignment.center,
textPosition: BarcodeTextPosition.below,
);
await FlutterBixolonPrinter.printBlankLines(1);
// Print QR Code
await FlutterBixolonPrinter.printCenteredText(
text: "QR CODE",
fontSize: 22,
);
await FlutterBixolonPrinter.printQRCode(
"https://pub.dev/packages/flutter_bixolon_printer",
size: 200,
alignment: Alignment.center,
);
await FlutterBixolonPrinter.cutPaper();
setState(() {
_status = "Barcode sample printed";
_isLoading = false;
});
} catch (e) {
setState(() {
_status = "Printing error: $e";
_isLoading = false;
});
}
}
Future<void> _printReceiptSample() async {
if (!_isConnected) {
_showNotConnectedMessage();
return;
}
setState(() {
_isLoading = true;
_status = "Printing receipt sample...";
});
try {
// Sample receipt data
final items = [
{'product': 'Coffee', 'qty': '1', 'price': '\$3.50'},
{'product': 'Sandwich', 'qty': '1', 'price': '\$5.75'},
{'product': 'Cookie', 'qty': '2', 'price': '\$2.00'},
];
await FlutterBixolonPrinter.printReceipt(
header: 'SAMPLE RECEIPT',
items: items,
footer: 'Thank you for your business!',
);
setState(() {
_status = "Receipt sample printed";
_isLoading = false;
});
} catch (e) {
setState(() {
_status = "Printing error: $e";
_isLoading = false;
});
}
}
void _showNotConnectedMessage() {
setState(() {
_status = "Not connected to a printer";
});
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('Please connect to a printer first'),
backgroundColor: Colors.red,
),
);
}
// Helper method to guess model name from device name
String _getModelFromName(String name) {
if (name.contains('R200')) return 'SPP-R200III';
if (name.contains('R210')) return 'SPP-R210';
if (name.contains('R310')) return 'SPP-R310';
if (name.contains('R400')) return 'SPP-R400';
// Default to R310 if model can't be determined
return 'SPP-R310';
}
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
primarySwatch: Colors.blue,
useMaterial3: true,
),
home: Scaffold(
appBar: AppBar(
title: const Text('Bixolon Printer Example'),
),
body: _isLoading
? const Center(child: CircularProgressIndicator())
: SingleChildScrollView(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
// Status display
Container(
padding: const EdgeInsets.all(12.0),
decoration: BoxDecoration(
color:
_isConnected ? Colors.green[100] : Colors.grey[200],
borderRadius: BorderRadius.circular(8),
),
child: Row(
children: [
Icon(
_isConnected ? Icons.check_circle : Icons.info,
color: _isConnected ? Colors.green : Colors.grey,
),
const SizedBox(width: 8),
Expanded(
child: Text(
_status,
style: TextStyle(
fontWeight: FontWeight.bold,
color: _isConnected
? Colors.green[800]
: Colors.black87,
),
),
),
],
),
),
const SizedBox(height: 24),
// Printer discovery section
const Text(
'Printer Discovery',
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 12),
ElevatedButton.icon(
onPressed: _scanPrinters,
icon: const Icon(Icons.search),
label: const Text('Scan for Printers'),
style: ElevatedButton.styleFrom(
padding: const EdgeInsets.symmetric(vertical: 12),
),
),
const SizedBox(height: 12),
// Printer selection dropdown
if (_devices.isNotEmpty) ...[
DropdownButtonFormField<PrinterDevice>(
decoration: const InputDecoration(
labelText: 'Select a printer',
border: OutlineInputBorder(),
),
value: _selectedDevice,
onChanged: (PrinterDevice? device) {
setState(() {
_selectedDevice = device;
});
},
items: _devices.map((printer) {
return DropdownMenuItem<PrinterDevice>(
value: printer,
child: Text(
'${printer.name} (${printer.connectionType.toString().split('.').last})',
overflow: TextOverflow.ellipsis,
),
);
}).toList(),
),
] else if (_devices.isEmpty &&
_status.contains('Found')) ...[
const Padding(
padding: EdgeInsets.all(8.0),
child: Text(
'No printers found. Make sure your printer is turned on and discoverable.',
style: TextStyle(fontStyle: FontStyle.italic),
),
),
],
const SizedBox(height: 24),
// Connection controls
const Text(
'Connection',
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 12),
Row(
children: [
Expanded(
child: ElevatedButton.icon(
onPressed: _isConnected ? null : _connectPrinter,
icon: const Icon(Icons.bluetooth_connected),
label: const Text('Connect'),
style: ElevatedButton.styleFrom(
padding: const EdgeInsets.symmetric(vertical: 12),
),
),
),
const SizedBox(width: 12),
Expanded(
child: ElevatedButton.icon(
onPressed: _isConnected ? _disconnectPrinter : null,
icon: const Icon(Icons.bluetooth_disabled),
label: const Text('Disconnect'),
style: ElevatedButton.styleFrom(
backgroundColor: Colors.red,
foregroundColor: Colors.white,
padding: const EdgeInsets.symmetric(vertical: 12),
),
),
),
],
),
const SizedBox(height: 24),
// Printing examples
const Text(
'Printing Examples',
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 12),
_buildPrintButton(
'Print Text Sample',
Icons.text_fields,
_printTextSample,
),
const SizedBox(height: 8),
_buildPrintButton(
'Print Barcode Sample',
Icons.qr_code,
_printBarcodeSample,
),
const SizedBox(height: 8),
_buildPrintButton(
'Print Receipt Sample',
Icons.receipt_long,
_printReceiptSample,
),
],
),
),
),
);
}
Widget _buildPrintButton(String text, IconData icon, VoidCallback onPressed) {
return ElevatedButton.icon(
onPressed: _isConnected ? onPressed : null,
icon: Icon(icon),
label: Text(text),
style: ElevatedButton.styleFrom(
padding: const EdgeInsets.symmetric(vertical: 12),
),
);
}
}