實現上面的效果須要的庫以下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