跳到内容
CrossFly 是 100% 开源在 GitHub 关注我们
CrossFlyCrossFly
开始使用

本页面由葡萄牙语机器翻译,可能存在错误。葡萄牙语版本为准。

BarcodePicker

BarcodePicker 从实时摄像头帧中读取条形码/二维码,并按格式过滤。它是一个抽象类:使用者实现 onBarcode(BarcodeFormat format, String code)。它遵循 picker 模式(见 Picker)——通过 getAnswer() 返回读取到的负载。

🔴 · 包: dev.crossfly.ui.picker · 继承: Picker implements GdxCamera.Listener(抽象) · 硬件: 摄像头

ℹ️ 这个 BarcodePicker 是通过摄像头读取,仍然存在。不要与旧的条形码生成工具(util/barcode)混淆,后者已在现代化过程中被移除。

何时使用

  • 扫描条形码(商品、门票)或二维码。

何时不要使用

外观

全屏摄像头预览(黑色背景),顶部标题,中央有一个用于对准的红色十字准星,右下角有一个白色的“X”关闭按钮。

完整示例(复制、粘贴并运行)

BarcodePicker 是抽象的:用一个实现 onBarcode 的类体来实例化它。由于它是一个摄像头叠加层,请从 Button 触发它。该示例复用了基本用法(1D 格式,首次读取即关闭),并将负载写入 Label。BarcodeFormat 来自 com.google.zxing。

package com.exemplo;

import com.google.zxing.BarcodeFormat;

import dev.crossfly.ui.*;
import dev.crossfly.ui.layout.*;
import dev.crossfly.ui.picker.*;

/** 可执行的主界面。将 launcher 指向此类(classname)并运行:gradlew :lwjgl3:run */
public class MainWindow extends Window
{
   @Override
   public void onShow() throws Exception
   {
      super.onShow();
      setLayout(new VerticalLayout());

      Label saida = new Label("Nenhum código lido");
      add(LAY_AUTO, saida);

      Button escanear = new Button("Escanear código")
         .onAction(c ->
         {
            BarcodePicker scanner = new BarcodePicker("Aponte para o código", BarcodePicker.formats1D)
            {
               protected void onBarcode(BarcodeFormat format, String code)
               {
                  onUI(() -> saida.setText(format + ": " + code)); // 返回 paint thread
                  hide(); // 首次读取后关闭(不会自动关闭)
               }
            };
            scanner.show(answer -> {});
         });
      add(LAY_AUTO, escanear);
   }
}

下面的代码片段只展示核心部分(放进 onShow() 内的内容)。要运行它们,请把它们放入上面的 MainWindow 骨架中。

基本用法

BarcodePicker scanner = new BarcodePicker("Aponte para o código", BarcodePicker.formats1D)
{
   protected void onBarcode(BarcodeFormat format, String code)
   {
      Debug.log(format + ": " + code);
      hide(); // 首次读取后关闭
   }
};
scanner.show(answer -> campoCodigo.setText((String) answer));

构造函数

构造函数 描述
BarcodePicker(String title, BarcodeFormat... formats) 标题 + 接受的格式(varargs;为空 = 全部)。抽象——用实现 onBarcode 的类体来实例化。

属性与自定义

成员 类型 默认值 作用
BarcodePicker.formats1D(静态) BarcodeFormat[] — 现成的 1D 格式集合(CODE_128、EAN_13……)。
BarcodePicker.formats2D(静态) BarcodeFormat[] — 现成的 2D 格式集合(QR_CODE)。
BarcodePicker.beep(静态) boolean true 解码时发出蜂鸣声。
BarcodePicker.vibrate(静态) boolean true 解码时震动。

回调与事件

回调 触发时机
onBarcode(BarcodeFormat, String) (抽象)解码到一个受支持格式的码时。
show(onAnswer) 关闭时,传递最后读取到的负载 String。

getAnswer() 返回最后解码到的负载,若取消则返回 null。

状态

  • 检测到时没有自动 hide() —— 是否关闭由你的 onBarcode(调用 hide())决定。不调用时,扫描器会继续读取(适用于连续读取)。
  • 连续重复的码(相同的 lastCode)会被忽略。
  • onAppPause/onAppResume 管理摄像头;onRemove 停止解码线程。

仅接受二维码并在首次读取时关闭

BarcodePicker scanner = new BarcodePicker("Leia o QR", BarcodePicker.formats2D)
{
   protected void onBarcode(BarcodeFormat format, String code)
   {
      onUI(() -> campoCodigo.setText(code)); // 在 paint 线程上更新 UI
      hide();
   }
};
scanner.show(answer -> Debug.log("Lido: " + answer));

最佳实践

  • 在 onBarcode 中调用 hide() 实现单次读取;省略则实现连续读取。
  • 解码在后台线程运行——将 UI 更新包裹在 onUI(...) 中。

常见错误

  • 忘记 hide() 却想要单次读取 —— 扫描器会持续激活。
  • 直接在 onBarcode 中更新 UI —— 请用 onUI(...) 遵守绘制线程。

另见

这个页面有帮助吗?