React Native 使用react-native-image-picker插件上传图片详细步骤

项目需要用到上传图片功能,经过一番折腾勉强完成需求,整理一下做个记录。插件选择是react-native-image-picker,还挺好用的,不过需要分ios和android不同平台去配置.http://www.jianshu.com/p/8dd405dbd663
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-image-picker来实现。以下是具体的实现步骤: 1. 安装react-native-image-picker使用npm或yarn命令进行安装: ``` npm install react-native-image-picker --save ``` 或者 ``` yarn add react-native-image-picker ``` 2. 导入库 在需要使用图片选择器的组件文件中导入库: ``` import ImagePicker from 'react-native-image-picker'; ``` 3. 添加图片选择器按钮 在需要添加图片选择器的地方添加一个按钮,点击该按钮会触发图片选择器的弹出: ``` <Button title="选择图片" onPress={this.selectImage} /> ``` 4. 实现图片选择器方法 定义一个selectImage方法,该方法将调用图片选择器,并且将选择的图片传递给回调函数: ``` selectImage = () => { const options = { title: '选择图片', cancelButtonTitle: '取消', takePhotoButtonTitle: '拍照', chooseFromLibraryButtonTitle: '从相册中选择', storageOptions: { skipBackup: true, path: 'images', }, allowsMultipleSelection: true, }; ImagePicker.showImagePicker(options, (response) => { if (response.didCancel) { console.log('用户取消了图片选择'); } else if (response.error) { console.log('图片选择器出错:', response.error); } else if (response.customButton) { console.log('自定义按钮被点击:', response.customButton); } else { console.log('选择的图片信息:', response); const { uri, fileName, type, fileSize } = response; // 将选择的图片传递给其他组件处理 this.props.onImageSelected({ uri, fileName, type, fileSize }); } }); } ``` 在该方法中,我们定义了图片选择器的参数options,其中allowsMultipleSelection为true表示可以选择多张图片。 然后调用ImagePicker.showImagePicker方法弹出图片选择器,选择的结果将传递给回调函数response,我们可以从response中获取选择的图片的信息,然后将其传递给其他组件进行处理。 以上就是使用react-native-image-picker实现React Native图片多选的步骤。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值