之前有搞过相机组件,如今也遇到了需求,顺便记录一下。
主要分为以下三步:
先上最终实现效果图:
一,版本介绍
以下是项目中使用的版本信息:
"react": "16.8.6",
"react-native": "0.60.5",
"react-native-camera": "^3.8.0"
想实现的功能是,可以扫描二维码,同时下方有按钮可以拍照及打开闪光灯。
二,安装使用
在 React-Native 0.60之后,安装使用非常的简单,而且不需要 link 。
1,首先,在项目根目录下执行 npm 安装命令,如下:
npm install react-native-camera@3.8.0
2,然后 ,需要 cd 进入 iOS 目录,执行 pod install,自动安装 iOS 端所需依赖。
3,需要在 iOS 的 Info.plist 中配置相机与麦克风权限,在安卓的 AndroidManifest.xml 中配置权限,如下图:
iOS 权限配置
android 权限配置
// android 添加至 AndroidManifest.xml 中
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<uses-permission android:name="android.permission.CAMERA"/>
// iOS 到 info.plist 中选择如下
Privacy - Microphone Usage Description
Privacy - Camera Usage Description
4,在 android/app/build.gradle 中增加如下配置:
android build.gradle 配置
三,界面实现
界面如下,包含返回、拍照及闪光灯(PS:由于模拟器,没有摄像头故是黑的)。
扫一扫界面
拍照或识别到二维码后,跳转到结果页面:
结果扫描页面
具体代码如下:
/**
* Created by supervons on 2019/10/20.
* 扫一扫及拍照页面
* explore page
*/
import React, { Component } from 'react';
import {
StyleSheet,
Text,
TouchableOpacity,
View,
Animated,
Easing
} from 'react-native';
import { RNCamera } from 'react-native-camera';
import {Icon, IconType} from 'react-native-elements';
export default class Scanner extends Component {
constructor(props) {
super(props);
this.state = {
moveAnim: new Animated.Value(0),
FlashMode: false,
showCamera: true
};
this.isBarcodeRead = false;
}
// 去掉导航条设置,全屏扫描
static navigationOptions = {
header: null
};
componentDidMount() {
this.startAnimation();
// 监听当结果页返回时,重新启动相机监听扫描事件
this.props.navigation.addListener("didFocus", () =>
this.setState({showCamera : true})
)
}
startAnimation = () => {
this.state.moveAnim.setValue(-200);
Animated.timing(this.state.moveAnim, {
toValue: 0,
duration: 1500,
easing: Easing.linear
}).start(() => this.startAnimation());
};
// 扫描事件
onBarCodeRead = result => {
if (!this.isBarcodeRead) {
this.isBarcodeRead = true;
// 卸载扫一扫组件,否则还会持续扫描
this.setState({showCamera: false})
this.props.navigation.navigate('ScannerResult', {
imageUri: null,
scannerResult: JSON.stringify(result)
});
}
};
// 拍照事件
takePicture = async () => {
if (this.camera) {
const options = { quality: 0.5, base64: true };
const data = await this.camera.takePictureAsync(options);
this.setState({showCamera: false})
this.props.navigation.push('ScannerResult', {
imageUri: data.uri,
scannerResult: ''
});
}
};
// 闪光灯开关
_changeFlashMode() {
this.setState({
FlashMode: !this.state.FlashMode
});
}
render() {
return (
<View style={styles.container}>
{this.state.showCamera ? (
<RNCamera
ref={ref => {
this.camera = ref;
}}
style={styles.preview}
type={RNCamera.Constants.Type.back}
flashMode={this.state.FlashMode ? 1 : 0}
onBarCodeRead={this.onBarCodeRead}
>
<View style={styles.rectangleContainer}>
<View style={styles.rectangle} />
<Animated.View
style={[
styles.border,
{ transform: [{ translateY: this.state.moveAnim }] }
]}
/>
<Text style={styles.rectangleText}>
将二维码放入框内,即可自动扫描
</Text>
<View style={{ flexDirection: 'row', marginTop: 15 }}>
<TouchableOpacity
onPress={()=>this.props.navigation.goBack()}
>
<Icon name='keyboard-arrow-left' size={36} color={'green'}/>
</TouchableOpacity>
<TouchableOpacity
onPress={this.takePicture.bind(this)}
style={{marginLeft: 25}}
>
<Icon name='camera' size={36} color={'green'}/>
</TouchableOpacity>
<TouchableOpacity
onPress={this._changeFlashMode.bind(this)}
style={{marginLeft: 25}}
>
<Icon name='highlight' size={36} color={this.state.FlashMode ? 'green' : 'gray'}/>
</TouchableOpacity>
</View>
</View>
</RNCamera>
) : (
<View />
)}
</View>
);
}
}
CSS如下
text: {
color: '#fff',
fontSize: 30,
fontWeight: 'bold'
},
container: {
flex: 1,
flexDirection: 'column'
},
preview: {
flex: 1,
justifyContent: 'flex-end',
alignItems: 'center'
},
rectangleContainer: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
backgroundColor: 'transparent'
},
rectangle: {
height: 200,
width: 200,
borderWidth: 1,
borderColor: '#00FF00',
backgroundColor: 'transparent'
},
rectangleText: {
flex: 0,
color: '#fff',
marginTop: 10
},
border: {
flex: 0,
width: 195,
height: 2,
backgroundColor: '#00FF00'
}
git项目地址:github.com/supervons/E…
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!