Flutter标签打印机插件niimbot_label_printer的使用

Flutter标签打印机插件niimbot_label_printer的使用

NiimbotLabelPrinter 是一个用于在 Flutter 应用程序中使用 Niimbot 标签打印机的包。该包提供了简单的接口来通过蓝牙连接到 Niimbot 打印机,管理连接,并发送打印数据。

特性

  • 请求蓝牙权限。
  • 检查蓝牙是否已启用。
  • 连接到和断开 Niimbot 打印机的连接。
  • 获取配对的蓝牙设备。
  • 向打印机发送打印数据。

安装

pubspec.yaml 文件中添加 niimbot_label_printer 依赖:

dependencies:
  niimbot_label_printer: ^0.0.1

使用

要使用 NiimbotLabelPrinter 插件,请遵循以下步骤:

  1. 请求蓝牙权限:
final bool result = await NiimbotLabelPrinter.requestPermissionGrant();
  1. 检查蓝牙是否已启用:
final bool result = await NiimbotLabelPrinter.bluetoothIsEnabled();
  1. 连接到 Niimbot 打印机:
final bool result = await NiimbotLabelPrinter.connect(device);
  1. 断开连接:
final bool result = await NiimbotLabelPrinter.disconnect();
  1. 获取配对的蓝牙设备:
final List<BluetoothDevice> devices = await NiimbotLabelPrinter.getPairedDevices();
  1. 发送打印数据到打印机:
final bool result = await NiimbotLabelPrinter.send(printData);
  1. 断开连接:
final bool result = await NiimbotLabelPrinter.disconnect();

示例代码

以下是完整的示例代码,展示了如何使用 NiimbotLabelPrinter 插件:

import 'dart:async';
import 'dart:ui' as ui;
import 'dart:ui';
import 'package:flutter/rendering.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:niimbot_label_printer/niimbot_label_printer.dart';
import 'package:niimbot_label_printer_example/custom_canvas_widget.dart';

void main() {
  runApp(const Apps());
}

class Apps extends StatelessWidget {
  const Apps({super.key});

  [@override](/user/override)
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: MyApp(),
    );
  }
}

class MyApp extends StatefulWidget {
  const MyApp({super.key});

  [@override](/user/override)
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  final TextEditingController txttext = TextEditingController();
  final TextEditingController txtwidth = TextEditingController(text: '50');
  final TextEditingController txtheight = TextEditingController(text: '30');
  final TextEditingController txtpixelformm = TextEditingController(text: '8');
  bool rotate = false;
  bool invertColor = false;
  int density = 3; //1 and 5
  int labelType = 1; // 1 and 3

  String _msj = 'Unknown';
  final NiimbotLabelPrinter _niimbotLabelPrinterPlugin = NiimbotLabelPrinter();
  List<BluetoothDevice> _devices = [];
  String macConnection = '';
  bool connecting = false;

  bool customImage = true;
  final globalKey = GlobalKey();
  List<TextInfo> texts = [];
  ui.Image? _image;
  double _width = 400;
  double _height = 240;

  [@override](/user/override)
  void initState() {
    super.initState();
  }

  [@override](/user/override)
  void dispose() {
    txtwidth.dispose();
    txtheight.dispose();
    txtpixelformm.dispose();
    super.dispose();
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Status: $_msj'),
        actions: [
          PopupMenuButton<String>(
            onSelected: (String value) async {
              switch (value) {
                case "permission_is_granted":
                  final bool result = await _niimbotLabelPrinterPlugin.requestPermissionGrant();
                  setState(() {
                    _msj = result ? 'Permission is granted' : 'Permission is not granted';
                  });
                  break;
                case "bluetooth_is_enabled":
                  final bool result = await _niimbotLabelPrinterPlugin.bluetoothIsEnabled();
                  setState(() {
                    _msj = result ? 'Bluetooth is enabled' : 'Bluetooth is not enabled';
                  });
                  break;
                case "is_connected":
                  final bool result = await _niimbotLabelPrinterPlugin.isConnected();
                  setState(() {
                    _msj = result ? 'Bluetooth is connected' : 'Bluetooth is not connected';
                  });
                  break;
                case "get_paired_devices":
                  final List<BluetoothDevice> result = await _niimbotLabelPrinterPlugin.getPairedDevices();
                  _devices = result;
                  setState(() {
                    _msj = "Devices ${result.length}";
                  });
                  break;
                case "disconnect":
                  final bool result = await _niimbotLabelPrinterPlugin.disconnect();
                  setState(() {
                    _msj = result ? 'Disconnected' : 'Not disconnected';
                  });
                  break;
              }
            },
            itemBuilder: (BuildContext context) =>
                <PopupMenuEntry<String>>[
              const PopupMenuItem<String>(
                value: "permission_is_granted",
                child: Text("Permission is granted"),
              ),
              const PopupMenuItem<String>(
                value: "bluetooth_is_enabled",
                child: Text("Bluetooth is enabled"),
              ),
              const PopupMenuItem<String>(
                value: "is_connected",
                child: Text("Is connected"),
              ),
              const PopupMenuItem<String>(
                value: "get_paired_devices",
                child: Text("Get paired devices"),
              ),
              const PopupMenuItem<String>(
                value: "disconnect",
                child: Text("Disconnect"),
              ),
            ],
          )
        ],
      ),
      body: Padding(
        padding: const EdgeInsets.all(8.0),
        child: SingleChildScrollView(
          child: Column(
            children: [
              Row(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                children: [
                  TextButton(
                    onPressed: () async {
                      modalCustomImage(context);
                    },
                    child: const Text('Toggle custom image'),
                  ),
                  TextButton(
                    onPressed: () async {
                      _image = await loadImage("assets/2.png");
                      setState(() {});
                    },
                    child: const Text('Toggle image assets'),
                  ),
                ],
              ),
              _image != null
                  ? Column(
                      children: [
                        Container(
                          decoration: BoxDecoration(
                            border: Border.all(color: Colors.black, width: 1),
                          ),
                          child: RawImage(image: _image!, width: _width, height: _height),
                        ),
                        Text("image. width: ${_image!.width}, height: ${_image!.height}"),
                      ],
                    )
                  : const SizedBox(),
              Visibility(
                visible: _image != null,
                child: Column(
                  children: [
                    Slider(
                      max: 3,
                      min: 1,
                      divisions: 2,
                      label: "Label type: ${labelType.toInt()}",
                      value: labelType.toDouble(),
                      onChanged: (value) {
                        setState(() {
                          labelType = value.toInt();
                        });
                      },
                    ),
                    Slider(
                      max: 5,
                      min: 1,
                      divisions: 4,
                      label: "Density: ${density.toInt()}",
                      value: density.toDouble(),
                      onChanged: (value) {
                        setState(() {
                          density = value.toInt();
                        });
                      },
                    ),
                    Row(
                      children: [
                        SizedBox(
                          width: 200,
                          child: CheckboxListTile(
                            value: rotate,
                            controlAffinity: ListTileControlAffinity.leading,
                            onChanged: (value) {
                              setState(() {
                                rotate = value!;
                                setState(() {});
                              });
                            },
                            title: const Text('Rotated'),
                          ),
                        ),
                        ElevatedButton(
                          onPressed: () async {
                            final bool isConnected = await _niimbotLabelPrinterPlugin.isConnected();
                            if (!isConnected) {
                              setState(() {
                                _msj = 'Not connected';
                              });
                              return;
                            }

                            ui.Image image = _image!;

                            ByteData? byteData = await image.toByteData();
                            List<int> bytesImage = byteData!.buffer.asUint8List().toList();
                            Map<String, dynamic> datosImagen = {
                              "bytes": bytesImage,
                              "width": image.width,
                              "height": image.height,
                              "rotate": rotate,
                              "invertColor": invertColor,
                              "density": density,
                              "labelType": labelType,
                            };
                            PrintData printData = PrintData.fromMap(datosImagen);
                            final bool result = await _niimbotLabelPrinterPlugin.send(printData);
                            setState(() {
                              _msj = result ? 'Printed' : 'Not printed';
                            });
                          },
                          style: ElevatedButton.styleFrom(backgroundColor: Colors.green, shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10))),
                          child: const Text('Print image', style: TextStyle(color: Colors.white)),
                        ),
                      ],
                    ),
                  ],
                ),
              ),
              SizedBox(
                height: 200,
                child: ListView.builder(
                  shrinkWrap: true,
                  itemCount: _devices.length,
                  itemBuilder: (BuildContext context, int index) {
                    BluetoothDevice device = _devices[index];
                    return ListTile(
                      selected: device.address == macConnection,
                      title: Text(device.name),
                      subtitle: Text(device.address),
                      leading: Visibility(
                        visible: connecting && device.address == macConnection,
                        child: const CircularProgressIndicator(strokeWidth: 1),
                      ),
                      onTap: () async {
                        setState(() {
                          connecting = true;
                          macConnection = device.address;
                        });
                        bool result = await _niimbotLabelPrinterPlugin.connect(device);
                        setState(() {
                          _msj = result ? 'Connected' : 'Not connected';
                          macConnection = device.address;
                          connecting = false;
                        });
                      },
                    );
                  },
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }

  void modalCustomImage(BuildContext context) async {
    double textSize = 10;
    bool isBold = false;
    bool isCenter = false;

    await showDialog(
      context: context,
      builder: (BuildContext context) {
        return BackdropFilter(
          filter: ImageFilter.blur(sigmaX: 10, sigmaY: 10),
          child: AlertDialog(
            shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(6)),
            content: StatefulBuilder(
              builder: (BuildContext context, StateSetter setState) {
                return SizedBox(
                  width: MediaQuery.of(context).size.width,
                  child: SingleChildScrollView(
                    child: Column(
                      mainAxisSize: MainAxisSize.min,
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [
                        Row(
                          mainAxisAlignment: MainAxisAlignment.spaceBetween,
                          children: [
                            const Text("Donate in PayPal", textAlign: TextAlign.center, style: TextStyle(fontSize: 20, color: Colors.black)),
                            IconButton(
                              onPressed: () {
                                Navigator.pop(context);
                              },
                              icon: const Icon(Icons.close),
                            ),
                          ],
                        ),
                        CustomQRWidget(
                          textList: texts,
                          qrData: "www.example.com",
                          width: _width,
                          height: _height,
                        ),
                        TextButton(
                          onPressed: () {
                            setState(() {
                              texts.clear();
                              txttext.clear();
                            });
                          },
                          child: const Text("Clear all"),
                        ),
                        Row(
                          children: [
                            Expanded(
                              child: TextField(
                                controller: txttext,
                                decoration: const InputDecoration(labelText: 'Text'),
                              ),
                            ),
                            TextButton(
                              onPressed: () {
                                setState(() {
                                  texts.add(
                                    TextInfo(
                                      text: txttext.text,
                                      fontSize: textSize,
                                      position: isCenter ? TextPosition.center : TextPosition.left,
                                      isBold: isBold,
                                    ),
                                  );
                                  txttext.clear();
                                });
                              },
                              child: const Text("Add text"),
                            ),
                          ],
                        ),
                        Text("fontSize: ${textSize.toInt()}"),
                        Slider(
                          value: textSize,
                          min: 10,
                          max: 90,
                          onChanged: (value) {
                            setState(() {
                              textSize = value;
                            });
                          },
                        ),
                        Row(
                          mainAxisAlignment: MainAxisAlignment.spaceBetween,
                          children: [
                            SizedBox(
                              width: 140,
                              child: CheckboxListTile(
                                value: isBold,
                                dense: true,
                                controlAffinity: ListTileControlAffinity.leading,
                                onChanged: (value) {
                                  setState(() {
                                    isBold = value!;
                                    setState(() {});
                                  });
                                },
                                title: const Text('Bold'),
                              ),
                            ),
                            SizedBox(
                              width: 140,
                              child: CheckboxListTile(
                                value: isCenter,
                                dense: true,
                                controlAffinity: ListTileControlAffinity.leading,
                                onChanged: (value) {
                                  setState(() {
                                    isCenter = value!;
                                    setState(() {});
                                  });
                                },
                                title: const Text('Center'),
                              ),
                            ),
                          ],
                        ),
                        Container(
                          padding: const EdgeInsets.all(5),
                          decoration: BoxDecoration(
                            border: Border.all(color: Colors.grey, width: 1),
                            borderRadius: BorderRadius.circular(4),
                          ),
                          child: Column(
                            crossAxisAlignment: CrossAxisAlignment.start,
                            children: [
                              const Text("Size label to print", style: TextStyle(fontSize: 8)),
                              const Text("The image can be created with a specific size and rotated before printing.", style: TextStyle(fontSize: 8)),
                              Row(
                                children: [
                                  SizedBox(
                                    width: 100,
                                    child: TextField(
                                      controller: txtwidth,
                                      decoration: const InputDecoration(labelText: 'Width mm'),
                                    ),
                                  ),
                                  SizedBox(
                                    width: 100,
                                    child: TextField(
                                      controller: txtheight,
                                      decoration: const InputDecoration(labelText: 'Height mm'),
                                    ),
                                  ),
                                ],
                              ),
                              SizedBox(
                                width: 200,
                                child: TextField(
                                  controller: txtpixelformm,
                                  decoration: const InputDecoration(labelText: 'Pixels per mm'),
                                ),
                              ),
                              ElevatedButton(
                                onPressed: () async {
                                  updateSize();
                                  _image = await CustomQRWidget.getImage(
                                    textList: texts,
                                    qrData: "www.example.com",
                                    width: _width,
                                    height: _height,
                                  );
                                  if (context.mounted) Navigator.pop(context);
                                },
                                style: ElevatedButton.styleFrom(backgroundColor: Colors.green, shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10))),
                                child: const Text('Create image', style: TextStyle(color: Colors.white)),
                              ),
                            ],
                          ),
                        ),
                      ],
                    ),
                  ),
                );
              },
            ),
          ),
        );
      },
    );

    setState(() {});
  }

  void updateSize() {
    int? width = int.tryParse(txtwidth.text);
    int? height = int.tryParse(txtheight.text);
    int? pixels = int.tryParse(txtpixelformm.text);
    if (width != null && height != null && pixels != null) {
      _width = width * pixels.toDouble();
      _height = height * pixels.toDouble();
      setState(() {});
    }
  }

  Future<ui.Image> resizeImage(ui.Image image, double targetWidth, double targetHeight) async {
    final recorder = ui.PictureRecorder();
    final canvas = Canvas(recorder);

    // Scale the image
    final paint = Paint();
    final scaleX = targetWidth / image.width;
    final scaleY = targetHeight / image.height;

    canvas.scale(scaleX, scaleY);
    canvas.drawImage(image, Offset.zero, paint);

    final resizedImage = await recorder.endRecording().toImage(
          targetWidth.toInt(),
          targetHeight.toInt(),
        );

    return resizedImage;
  }

  Future<ui.Image> loadImage(String asset) async {
    final ByteData data = await rootBundle.load(asset);
    final Uint8List bytes = data.buffer.asUint8List();
    final Completer<ui.Image> completer = Completer();
    ui.decodeImageFromList(bytes, (ui.Image img) {
      //print("Image loaded, size: ${img.width}x${img.height}");
      completer.complete(img);
    });

    return completer.future;
  }
}

更多关于Flutter标签打印机插件niimbot_label_printer的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter标签打印机插件niimbot_label_printer的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是如何在Flutter项目中集成并使用niimbot_label_printer插件的详细指南和代码示例。这个插件假设是用于与标签打印机进行交互的。

第一步:添加依赖

首先,在你的Flutter项目的pubspec.yaml文件中添加niimbot_label_printer依赖:

dependencies:
  flutter:
    sdk: flutter
  niimbot_label_printer: ^latest_version  # 请替换为插件的实际最新版本号

然后运行以下命令来获取依赖:

flutter pub get

第二步:导入插件

在你需要使用标签打印功能的Dart文件中导入插件:

import 'package:niimbot_label_printer/niimbot_label_printer.dart';

第三步:配置权限(如果需要)

某些标签打印机可能需要特定的权限,如蓝牙权限。确保在AndroidManifest.xmlInfo.plist中配置必要的权限。

对于Android,你可能需要在AndroidManifest.xml中添加以下权限:

<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<uses-permission android:name="android.permission.BLUETOOTH_SCAN"/>
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT"/>

对于iOS,在Info.plist中添加蓝牙权限描述:

<key>NSBluetoothAlwaysUsageDescription</key>
<string>This app needs access to bluetooth to print labels</string>
<key>NSBluetoothPeripheralUsageDescription</key>
<string>This app needs access to bluetooth to print labels</string>

第四步:使用插件

以下是一个使用niimbot_label_printer插件的示例代码,展示了如何初始化打印机、连接打印机并发送打印任务:

import 'package:flutter/material.dart';
import 'package:niimbot_label_printer/niimbot_label_printer.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  NiimbotLabelPrinter? _printer;
  String _status = "Initializing...";

  @override
  void initState() {
    super.initState();
    _initializePrinter();
  }

  Future<void> _initializePrinter() async {
    try {
      _printer = NiimbotLabelPrinter();
      await _printer!.initialize();
      setState(() {
        _status = "Printer Initialized";
      });
      // 连接打印机(这里假设你已经有打印机的地址或标识符)
      // await _printer!.connect("printer_address_or_identifier");
      // 发送打印任务
      // await _sendPrintJob();
    } catch (e) {
      setState(() {
        _status = "Error: ${e.message}";
      });
    }
  }

  Future<void> _sendPrintJob() async {
    if (_printer == null || !_printer!.isConnected) {
      setState(() {
        _status = "Printer not connected";
      });
      return;
    }

    String labelData = "Hello, this is a test label!";
    try {
      await _printer!.printLabel(labelData);
      setState(() {
        _status = "Label printed successfully";
      });
    } catch (e) {
      setState(() {
        _status = "Error printing label: ${e.message}";
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Label Printer Example'),
        ),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Text(_status),
              SizedBox(height: 20),
              ElevatedButton(
                onPressed: () async {
                  // 假设这里处理连接打印机的逻辑
                  // await _printer!.connect("printer_address_or_identifier");
                  await _sendPrintJob();
                },
                child: Text('Print Label'),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

注意事项

  1. 连接打印机:在实际应用中,你需要根据打印机的类型(蓝牙、USB、网络等)来连接打印机。上面的代码只是一个示例,并没有展示具体的连接逻辑。

  2. 打印数据格式:标签数据(labelData)的格式取决于你的打印机和标签纸类型。确保你发送的数据格式与打印机兼容。

  3. 错误处理:在生产环境中,你应该添加更多的错误处理逻辑,以确保应用的健壮性。

希望这些代码示例和说明能帮助你在Flutter项目中成功集成和使用niimbot_label_printer插件。如果有任何问题,请查阅插件的官方文档或联系插件的维护者。

回到顶部