美文网首页React Native 整理
React Native 使用react-native-imag

React Native 使用react-native-imag

作者: JMCC117 | 来源:发表于2017-03-30 17:25 被阅读0次

    项目需要用到上传图片功能,经过一番折腾勉强完成需求,整理一下做个记录。插件选择是react-native-image-picker,还挺好用的,不过需要分ios和android不同平台去配置.
    IOS:
    1.在Xcode右击项目选择Add Files to 'XXX',(这里的xxx就是你的项目).然后找到项目的node_modules ➜ react-native-image-picker ➜ ios ➜ select RNImagePicker.xcodeproj添加进去。
    2.在Build Phases的Link Binary With Libraries中添加RNImagePicker.a

    Android:
    1.在android/settings.gradle文件中添加如下代码

    include ':react-native-image-picker'
    project(':react-native-image-picker').projectDir = new File(settingsDir, '../node_modules/react-native-image-picker/android')
    

    2.在android/app/build.gradle文件的dependencies中添加如下代码:

    compile project(':react-native-image-picker')
    

    3.在AndroidManifest.xml文件中添加

    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    

    4.最后在MainApplication.java文件中添加如下代码:其中new代码加到new MainReactPackage()所在位置。

    import com.imagepicker.ImagePickerPackage;
     new ImagePickerPackage()
    

    以上就配置好了,ios如果是10+的系统还需另外增加配置,这里就不说了。因为项目中用到这个功能的地方不止一处,所以就封装成一个插件了,名为CameraButton.js。代码如下(去掉了一些实际项目中的逻辑,可能看起来有点怪)

    import React from 'react'
    import {
        TouchableOpacity,
        StyleSheet,
        Platform,
        ActivityIndicator,
        View,
        Text,
        ToastAndroid
    } from 'react-native'
    
    var ImagePicker = require('react-native-image-picker');
    import Icon from 'react-native-vector-icons/Ionicons';
    
    const options = {
        title: '选择图片', 
        cancelButtonTitle: '取消',
        takePhotoButtonTitle: '拍照', 
        chooseFromLibraryButtonTitle: '图片库', 
        cameraType: 'back',
        mediaType: 'photo',
        videoQuality: 'high', 
        durationLimit: 10,
        maxWidth: 600,
        maxHeight: 600,
        aspectX: 2, 
        aspectY: 1,
        quality: 0.8,
        angle: 0,
        allowsEditing: false,
        noData: false,
        storageOptions: { 
            skipBackup: true, 
            path: 'images'
        }
    };
    
    class CameraButton extends React.Component {
        constructor(props){
            super(props);
            this.state = {
                loading:false
            }
        }
        render() {
            const {photos,type} = this.props;
            let conText;
            if(photos.length > 0){
                conText = (<View style={styles.countBox}>
                    <Text style={styles.count}>{photos.length}</Text>
                </View>);
            }
            return (
                <TouchableOpacity
                    onPress={this.showImagePicker.bind(this)}
                    style={[this.props.style,styles.cameraBtn]}>
                    <View>
                        <Icon name="md-camera" color="#aaa" size={34}/>
                        {conText}
                    </View>
                </TouchableOpacity>
            )
        }
    
        showImagePicker() {
            ImagePicker.showImagePicker(options, (response) => {
                if (response.didCancel) {
                    console.log('User cancelled image picker');
                }
                else if (response.error) {
                    console.log('ImagePicker Error: ', response.error);
                }
    
                else {
    
                    let source;
    
                    if (Platform.OS === 'android') {
                        source = {uri: response.uri, isStatic: true}
                    } else {
                        source = {uri: response.uri.replace('file://', ''), isStatic: true}
                    }
    
    
    
    
                    let file;
                    if(Platform.OS === 'android'){
                        file = response.uri
                    }else {
                        file = response.uri.replace('file://', '')
                    }
    
    
                    this.setState({
                        loading:true
                    });
                    this.props.onFileUpload(file,response.fileName||'未命名文件.jpg')
                    .then(result=>{
                        this.setState({
                            loading:false
                        })
                    })
                }
            });
        }
    }
    const styles = StyleSheet.create({
        cameraBtn: {
            padding:5
        },
        count:{
            color:'#fff',
            fontSize:12
        },
        fullBtn:{
            justifyContent:'center',
            alignItems:'center',
            backgroundColor:'#fff'
        },
        countBox:{
            position:'absolute',
            right:-5,
            top:-5,
            alignItems:'center',
            backgroundColor:'#34A853',
            width:16,
            height:16,
            borderRadius:8,
            justifyContent:'center'
        }
    });
    
    export default CameraButton;
    

    然后在需要用到的地方引入

    import CameraButton from '../../component/huar/cameraButton'
    
    View称代码:(简洁)
                        <CameraButton style={styles.cameraBtn}
                                      photos={[]}
                                      onFileUpload={this.onFileUpload} />
    点击事件:
        onFileUpload(file, fileName){
            return this.props.uploadAvatar({
                id: this.props.user.ID,
                type:'logo',
                obj:'user',
                corpId: this.props.cropId
            }, file, fileName)}
     Action请求代码:
    function actions(dispatch) {
        return {
            fileUrl,fileName)=>dispatch(Actions.uploadAvatar(params, fileUrl,fileName))
        }
    }
    

    上面已经获取到数据,接下来就是上传了。(uploadAvatar中第一个对象是项目上传需要用到的参数)

    actions中的uploadAvatar函数如下

    function uploadAvatar(params, fileUrl, fileName) {
        return dispatch=> {
            return UserService.uploadImage(params, fileUrl, fileName)
                .then(result=> {
                    dispatch({
                        type: UPDATE_AVATAR,
                        path: result.path
                    })
                    return result
                })
        }
    }
    

    UserService.uploadImage的代码如下

    export function uploadImage(params, fileUrl,fileName) {
        return http.uploadFile(`${config.UploadImage}`, params, fileUrl,fileName)
    }
    

    $中是上传的地址.我们用的是FontDate上传,在http中的uploadFile函数代码如下:

    let queryString = require('query-string');
    import Storage from './storage'
    import {
        Platform
    } from 'react-native'
    
    const os = Platform.OS;
    
    async function uploadFile(url, params, fileUrl,fileName) {
        let Access_Token = await Storage.getItem('Access_Token');
        let data = new FormData();
    
        data.append('file', {
            uri: fileUrl,
            name: fileName,
            type: 'image/jpeg'
        });
    
        Object.keys(params).forEach((key)=> {
            if (params[key] instanceof Date) {
                data.append(key, value.toISOString())
            } else {
                data.append(key, String(params[key]))
            }
        });
        
        const fetchOptions = {
            method: 'POST',
            headers: {
                'Accept': 'application/json',
                'Access_Token': Access_Token ? Access_Token : '',
                'UserAgent':os
            },
            body: data
        };
    
    
        return fetch(url, fetchOptions)
            .then(checkStatus)
            .then(parseJSON)
    }
    

    因为上传需要判断token 所以用了async/await。

    相关文章

      网友评论

        本文标题:React Native 使用react-native-imag

        本文链接:https://www.haomeiwen.com/subject/awzdottx.html