实现上面的效果须要的库以下react
react-native-image-picker
react-native-progressspring
先来讲下是如何实现点击上传图标弹出optionModal上传选项的动画的.react-native
整个optionModal区域是一个Animated.View, render 的时候他的position 是 absolute的, 整个位置是隐藏在屏幕下的, bottom: - 200. 点击按钮以后,用Animated.spring 把 bottom 的值 调整到 0 , 这样隐藏的部分就弹出来了。app
const styles = StyleSheet.create({ container: { backgroundColor: theme.screen_background_color, zIndex: 100, height: 200, width: '100%', position: 'absolute', bottom: - 200), backgroundColor: 'rgb(255,255,255)', alignItems: 'center', borderTopWidth: 1, borderTopColor: theme.divider_color, } showOptionModal() { Animated.spring( this.modalPos, { toValue: 0, } ).start(); <Animated.View style={[styles.container, { bottom: this.modalPos }]}> </Animated.View>
还有就是区域里面的upload video 和 upload photos 图标动画有个前后顺序,这里的处理就是upload video 这个图标用了个settimeout, 让他的动画触发晚了个 0.1秒而已。实现的方法也是跟optionModal弹出的方法同样。ide
接下来就是选择手机里面的图片或者视频了,这里咱们会用一个库叫作 react-native-image-picker, 这个库应该是你们很常常会使用到的, 就是选择手机里面的视频和图片,或者能够用摄像头拍摄图片. 当咱们点击 upload photos 的时候, 触发下面的代码就能够开始选择图片了动画
ImagePicker.showImagePicker({ title: null, cancelButtonTitle: 'cancel', allowsEditing: true, chooseFromLibraryButtonTitle: 'choose from camera roll', takePhotoButtonTitle: type==='video'?null:'open camera', mediaType: type, noData: true, quality: 0.5, videoQuality: 'medium', storageOptions: { skipBackup: true, cameraRoll: true, waitUntilSaved: true, }, }, (response) => { if (!response.didCancel && !response.error) { //能够在这里上传图片了 this.startUpload(response); } return null; }); }
当图片选择完毕以后, 就会触发this.startUpload(response); 了, 下面就是如何处理图片上传阿里云的部分了。 在上传文件到阿里云oss 以前呢 须要从Oss获取几个配置项,OSSAccessKeyId,Signature,key, police, 能够看下Oss 文档,这个须要你本身搞定啦。this
startUpload(response){ const uploadMediaData = new FormData(); uploadMediaData.append('OSSAccessKeyId', accessKeyId); uploadMediaData.append('policy', policy); uploadMediaData.append('Signature', signature); uploadMediaData.append('key', key); uploadMediaData.append('success_action_status', 201); uploadMediaData.append('file', { uri: response.uri, type: 'multipart/form-data', name: response.fileName, }); // 上传成功 successResponse = (xhr) => { let returnKey = xhr.responseText.match(/<Key>([^<]*)<\/Key>/)[1]; //这个key 就是你上传文件在oss 的地址了, }; //上传失败 failResponse = () => { // to do }; //开始上传 const OSS_UPLOAD_URI = 'http://xxxxx.oss-us-east-1.aliyuncs.com' futch(OSS_UPLOAD_URI, { method: 'POST', body: uploadMediaData, extra: null, }, (progressEvent) => { // progress 就是上穿的进度, 更新 state 里面的uploadProgress const progress = (progressEvent.loaded / progressEvent.total); this.setState({ uploadProgress: progress, }) }, (xhr) => successResponse(xhr), failResponse) .then((res) => console.log(res), (err) => console.log('error' + err)); } //这个方法就是具体上传的代码了 futch = (url, opts = {}, onProgress, successResponse, failResponse) => { return new Promise((res, rej) => { let xhr = new XMLHttpRequest(); xhr.open(opts.method || 'get', url); for (let k in opts.headers || {}) xhr.setRequestHeader(k, opts.headers[k]); xhr.onload = e => res(e); xhr.onreadystatechange = (e) => { if (xhr.readyState !== 4) { return; } //阿里云的状态码201 才有返回的信息 if (xhr.status === 201) { xhr.extra = opts.extra; successResponse(xhr); } else { xhr.extra = opts.extra; failResponse(xhr); } }; xhr.onerror = rej; if (xhr.upload && onProgress) xhr.upload.onprogress = onProgress; xhr.setRequestHeader('Content-Type', 'multipart/form-data'); xhr.send(opts.body); }); }
若是一切都ok 的话, 这个时候在上传的过程当中就应该出现进度条了,
上面提到了,this.state.uploadProgress 是用来存储上传进度的, 咱们就利用这个做为进度条的数据源了, 由于咱们用的是圆形的进度条,这里须要另一个库, ' react-native-progress'.阿里云
import ProgressCircle from 'react-native-progress/Circle'; //render 的时候只要把this.state.uploadProgress 丢进去就好了 <ProgressCircle size={30} showsText={true} size={100} progress={uploadProgress} color={‘#32CDFF’} thickness={4} borderWidth={2} style={styles.progressCircle} />
这里特别提出一下,oss 的上传成功的返回代码是201。这样整个过程就结束了, 其中有些细节没提出来,须要你们本身完善,可是大概的流程应该都写出来了. 但愿对大你们有用。url