HmsScanView
底层 headless 扫码相机组件:只渲染相机预览并发出扫码事件,取景框 / 扫描线 / 手电按钮等 UI 由上层(如 <Scanner>)用普通 RN 视图叠加绘制。需要自定义扫码界面时用它;要开箱即用的整屏扫码页用 <Scanner>。
import { HmsScanView } from '@unif/react-native-hms-scan';
原生实现:Android = 华为 RemoteView(Scan SDK-Plus),iOS = HmsCustomScanViewController(ScanKitFrameWork)。
签名
const HmsScanView: ForwardRefExoticComponent<
HmsScanViewProps & RefAttributes<...>
>
HmsScanViewProps 继承自 ViewProps——所有标准 View props(如 style)均可传入。
Props
| Prop | 类型 | 默认值 | 说明 |
|---|---|---|---|
style | StyleProp<ViewStyle> | — | 布局样式,通常设 StyleSheet.absoluteFill 或 { flex: 1 }(继承自 ViewProps) |
formats | BarcodeFormat[] | — | 限定识别码制;不传 = 全部(14 种) |
continuous | boolean | true | 连续扫码模式;false 命中后停止 |
paused | boolean | false | 暂停 / 恢复扫码;命中后置 true 可停在结果画面 |
torch | boolean | false | 手电筒开关(iOS 为 best-effort,见平台差异) |
onScanResult | (results: ScanResult[]) => void | — | 命中一个或多个码时回调(原生 JSON 已解析为强类型) |
onScanError | (error: { code: string; message: string }) => void | — | 相机 / 解码出错时回调,见 error.code |
onTorchStatus | (status: TorchStatus) => void | — | 手电 / 暗光状态变化时回调,见 TorchStatus |
formats 变更会重建相机
两端都在初始化时按 formats 创建扫码器,运行中改变 formats(或 continuous)会重建底层相机视图。若需频繁切换码制,建议传一个稳定的全集而非频繁变更。
TorchStatus
onTorchStatus 回调参数类型。
| 字段 | 类型 | 说明 |
|---|---|---|
available | boolean | 暗光提示:环境暗到建议显示手电按钮(仅 Android 据环境光上报) |
on | boolean | 手电当前是否点亮 |
available 的暗光语义仅 Android
available 作为「环境暗、建议显示手电」的提示只有 Android 会据环境光上报(来自华为 OnLightVisibleCallBack)。iOS 上 onTorchStatus 仅在你改变 torch prop 时触发,其 available 反映的是「设备是否有手电硬件」、不是环境光信号——不要把它当跨平台的暗光提示。详见平台差异。
error.code
onScanError 回调的 error.code(字符串;不是 HmsScanError 实例):
code | 平台 | 含义 |
|---|---|---|
E_CAMERA_INIT | Android | 相机 / 预览初始化失败(如无宿主 Activity) |
E_NO_RESULT | iOS | 解码结果为空或无法解析(软错误) |
<HmsScanView>不含权限请求逻辑——渲染前需先确认已获得相机权限(见指南 → 权限处理)。<Scanner>会自动处理权限。
示例
import { useState } from 'react';
import { View, StyleSheet } from 'react-native';
import { HmsScanView, type ScanResult } from '@unif/react-native-hms-scan';
function CustomScan() {
const [paused, setPaused] = useState(false);
const [torch, setTorch] = useState(false);
return (
<View style={{ flex: 1 }}>
<HmsScanView
style={StyleSheet.absoluteFill}
formats={['QR_CODE', 'EAN_13']}
torch={torch}
paused={paused}
onScanResult={(results: ScanResult[]) => {
const code = results[0]?.value;
if (code) setPaused(true); // 命中后停帧
}}
onScanError={(e) => {
// e.code: 'E_CAMERA_INIT'(Android)/ 'E_NO_RESULT'(iOS)
}}
onTorchStatus={(status) => {
// Android: status.available 为暗光提示;iOS 仅 torch 变更时触发
}}
/>
{/* 自定义取景框 / 按钮叠加在这里 */}
</View>
);
}
更多模式见指南 → 底层 headless 组件。
注意事项
paused置true时相机画面保持但停止解码,适合命中后停帧展示结果。continuous模式下同一帧可能多次回调,业务侧需自行去重(如置paused)。torch在 iOS 端为 best-effort 实现,详见平台差异。
平台兼容性
| 平台 | 支持 | 备注 |
|---|---|---|
| iOS(真机) | ✅ | torch best-effort;onTorchStatus.available 非暗光信号;模拟器无法扫码 |
| Android | ✅ | 全功能支持 |
| Web | ❌ | — |
相关
- 平台差异 — 手电筒与暗光提示的详细对比
- 指南 → 底层 headless 组件 — 使用示例与典型模式
- API 参考 → Scanner — 开箱即用的成品扫码页
- API 参考 → 类型 —
ScanResult/BarcodeFormat