跳到主要内容

Scanner

成品「扫一扫」界面(聚焦款,浅色)。底层使用 <HmsScanView> 出相机画面,取景框 / 工具栏 / 结果卡全用 @unif/react-native-design 的主题令牌与组件绘制。自带 ThemeProvider、权限流和状态机,可直接整屏接入。

ToastHost 由宿主按需在 App 根部挂载。

import { Scanner } from '@unif/react-native-hms-scan';

签名

function Scanner(props: ScannerProps): JSX.Element

Props

Prop类型默认值说明
titlestring'扫一扫'顶栏标题
formatsreadonly BarcodeFormat[]限定识别码制;不传 = 全部(14 种
hintTextstring'将条码 / 二维码放入框内,自动扫描'取景态提示文案
topInsetnumber54顶部安全区高度(px)。用 react-native-safe-area-context 时传 insets.top
bottomInsetnumber34底部安全区高度(px)。用 react-native-safe-area-context 时传 insets.bottom
showTorchbooleantrue是否显示手电筒按钮。手电由库内自管,最终以 onTorchStatus.on 的真实点亮状态回写标签;Android 可编程控制,iOS 为 best-effort(见平台差异),可在 iOS 传 false 隐藏
onClose() => void返回按钮回调(退出扫码页;按钮在底部工具栏,与手电筒并排)
onScanError(error: ScanError) => void权限 helper 或相机扫码出错时上报普通 { code, message };不是 HmsScanError,见错误回调
resolveProduct(result: ScanResult) => ScanProduct | null | undefined | Promise<ScanProduct | null | undefined>扫到条码后由宿主解析商品信息(用于浮层确认卡)。返回 null / undefined 或抛错 = 未识别 → 进入 fail 重扫层。不传则以 result.value 作为商品名
onConfirm(product: ScanProduct, result: ScanResult) => void用户点"确定"时回调(宿主通常在此导航返回)。autoConfirm 为真时由库自动触发
autoConfirmbooleanfalse传了 onConfirm 时,扫到并解析成功后不显示结果卡,直接触发 onConfirm(product, result);只有 onConfirm 同步正常返回后才进入 done,相机保持暂停且不自动重扫。onConfirm 同步抛错则进入 fail 重扫。未传 onConfirm 时回退结果卡;未识别(resolveProduct 返回 null / 抛错)也进入 fail,不会误触发
pickImage() => Promise<string | null>点"相册":宿主用自己的图片选择器选图并返回本地 uri(取消返回 null)。库不内置图片选择器:传了才显示相册按钮,不传则隐藏
返回 / 手电 / 相册按钮的显隐

工具栏在取景态显示,只要 showTorch 为真、传了 pickImage传了 onClose 任一即出现:返回按钮在传了 onClose 时显示,手电按钮受 showTorch 控制,相册按钮仅在传了 pickImage 时显示。pickImage 返回的本地 uri 会交给 decodeImage 识别(受同样的 URI 规则 约束)。


回调用到的类型

ScanResult

resolveProduct / onConfirm 收到的扫码结果。完整定义见 类型 → ScanResult

字段类型必填说明
valuestring原始解码文本
formatBarcodeFormat码制
contentTypeBarcodeContentType内容语义类型(可能缺省)
cornerPointsScanCornerPoint[]条码四角点(可能缺省)

ScanProduct

resolveProduct 返回、用于浮层确认卡展示的商品信息。仅 name 必填。完整定义见 类型 → ScanProduct

字段类型必填说明
namestring商品名
brandstring品牌
brandCharstring字母牌字符;缺省取 brand / name 首字
barcodestring条码;缺省取扫到的 value
specstring规格
stockShortstring库存短描述
pricestring价格展示串
priceCaptionstring价格副标题,默认 "建议零售"

ScanError

onScanError 收到的是普通对象,不是 HmsScanError 实例:

onScanError?: (error: ScanError) => void;
// error: { code: string; message: string }

可能包括 E_CAMERA_INITE_NO_RESULTE_NO_ACTIVITYE_UNKNOWN 等 code。view error 分三路:E_NO_RESULT 是 soft error,只上报、不离开当前扫码态;E_NO_CAMERA_PERMISSION 进入 denied 权限遮罩并卸载相机 view;其余 fatal view error 进入带「重试」按钮的 error。权限 helper reject 同样进入 error


示例

import { Scanner, type ScanResult, type ScanProduct } from '@unif/react-native-hms-scan';
import { useSafeAreaInsets } from 'react-native-safe-area-context';

function ScanScreen({ navigation }) {
const insets = useSafeAreaInsets();
return (
<Scanner
title="扫一扫"
topInset={insets.top}
bottomInset={insets.bottom}
formats={['QR_CODE', 'EAN_13']}
onClose={() => navigation.goBack()}
resolveProduct={async (r: ScanResult): Promise<ScanProduct | null> => {
const p = await api.lookupByBarcode(r.value);
return p ? { name: p.name, price: `¥${p.price}` } : null;
}}
onConfirm={(product, result) => {
navigation.navigate('Order', { barcode: result.value, product });
}}
pickImage={async () => {
const res = await launchImageLibrary({ mediaType: 'photo' });
return res.assets?.[0]?.uri ?? null;
}}
/>
);
}

注意事项

  • 挂载时自动请求相机权限:已授权直接进入取景;永久拒绝(blocked)展示引导去系统设置的遮罩。从系统设置授权返回后会自动重新查询权限。
  • 内部状态机:init → scan → detecting → success / fail / denied / error / done,一次扫一个。手动确认或重扫后回 scan;autoConfirm 在有 onConfirm 时成功后进 done,相机保持暂停且不自动重扫;未传回调则显示结果卡。
  • autoConfirmdone 的前提是 onConfirm 正常返回:它与 resolveProduct 在同一个 try 里调用,onConfirm 同步抛错会被收成 fail 重扫层,不会到达 done。宿主导航可能抛错时,请在 onConfirm 内部自行 try/catch。
  • view error 分三路:E_NO_RESULT 只通过 onScanError soft 上报;E_NO_CAMERA_PERMISSION 进入 denied 并卸载相机 view;其余 fatal view error 进入可重试的 error。权限 helper reject 与打开系统设置失败也进入 error
  • resolveProduct 抛错与返回 null / undefined 效果相同,均进入 fail 重扫层。
  • 自带 ThemeProvider;放进宿主已有的 ThemeProvider 里也兼容(嵌套不报错)。
  • @unif/react-native-design 是 peer 依赖,<Scanner> 的 UI 依赖它(及其链上的 react-native-reanimated / react-native-gesture-handler)。

平台兼容性

平台支持备注
iOS(真机)官方 ScanKitFrameWork 1.1.2.305 CocoaPod;手电 best-effort
iOS Simulator原生目标不支持;无硬件 JS 逻辑使用随包 Jest mock(见平台差异
Android全功能支持
Web

相关