跳到主要内容

Scanner

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

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

签名

function Scanner(props: ScannerProps): JSX.Element

Props

Prop类型默认值说明
titlestring'扫一扫'顶栏标题
formatsBarcodeFormat[]限定识别码制;不传 = 全部(14 种
hintTextstring'将条码 / 二维码放入框内,自动扫描'取景态提示文案
topInsetnumber54顶部安全区高度(px)。用 react-native-safe-area-context 时传 insets.top
bottomInsetnumber34底部安全区高度(px)。用 react-native-safe-area-context 时传 insets.bottom
showTorchbooleantrue是否显示手电筒按钮。手电由库内自管:Android 可编程控制,iOS 为 best-effort(见平台差异),可在 iOS 传 false 隐藏
onClose() => void返回按钮回调(退出扫码页;按钮在底部工具栏,与手电筒并排)
resolveProduct(result: ScanResult) => ScanProduct | null | undefined | Promise<ScanProduct | null | undefined>扫到条码后由宿主解析商品信息(用于浮层确认卡)。返回 null / undefined 或抛错 = 未识别 → 进入 fail 重扫层。不传则以 result.value 作为商品名
onConfirm(product: ScanProduct, result: ScanResult) => void用户点"确定"时回调(宿主通常在此导航返回)。autoConfirm 为真时由库自动触发
autoConfirmbooleanfalse扫到并解析成功后不显示结果卡,直接触发 onConfirm(product, result)。适合"扫到即用、无需二次确认"。回调后相机暂停、不自动重扫(宿主通常在 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价格副标题,默认 "建议零售"

示例

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一次扫一个(扫到 results[0] 进 detecting,确定或重扫后回 scan)。
  • resolveProduct 抛错与返回 null / undefined 效果相同,均进入 fail 重扫层。
  • 自带 ThemeProvider;放进宿主已有的 ThemeProvider 里也兼容(嵌套不报错)。
  • @unif/react-native-design 是 peer 依赖,<Scanner> 的 UI 依赖它(及其链上的 react-native-reanimated / react-native-gesture-handler)。

平台兼容性

平台支持备注
iOS(真机)手电 best-effort;模拟器无法扫码(见平台差异
Android全功能支持
Web

相关