react native常见第三方库集成(四)

注意:我主要用的包管理工具是yarn(也可以用npm或者cnpm);这里只介绍第三方库的基本集成,属性和方法可以去参考文章和github查找学习。

个人意见:集成第三方库最好不要制定固定的版本,因为可能会和你的react native版本不相符,导致报错!!!

这篇文章主要记录一些 react-native-image-crop-picker 和 react-native-image-zoom-viewer 的基本用法....

前言:目前大多数app中图片展示是一个非常常见的功能,在实际开发中,上传图片,设置头像等功能更是屡见不鲜。而在react native的开发前提下,这些需求也变得越来越频繁;但是react native框架本身在拍照和图片选择这方面并没有很好的解决方法。而众多优秀的开源库却可以让我们实现非常好的效果并且使用也比较简单。如:react-native-image-crop-picker,该库实现了本地相册和照相机来采集图片,并且提供多选、图片裁剪等功能,支持iOS和Android两个平台,但需要分别配置。另外:react-native-image-picker这个库也不错,实现启动本地相册和照相机来采集图片,但是作者没有实现裁剪功能。

react-native-image-crop-picker

一、安装:

yarn add react-native-image-crop-picker(npm i react-native-image-crop-picker --save)

          yarn add react-native-image-crop-picker@0.16.0  ==>> 我是指定安装的 0.16.0 版本

link:react-native link react-native-image-crop-picker  ==>>自动配置react-native-image-crop-picker在环境中的一些修改(不是全部)

 

二、配置

android平台:

  •  android平台的Gradle版本必须大于2.2,例如React Native 0.44 创建项目,查看工程的build.gradle中默认gradle版本         

          

  • 在app下的build.gradle中添加useSupportLibrary,添加在android / defaultConfig / 节点下   

          ===>>>   vectorDrawables.useSupportLibrary = true

          

  • AndroidManifest.xml配置文件,添加相机权限  ==>> 可以打开相机

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

          

 

三、页面中简单使用

import React, {Component} from "react";
import {
    View,
    Text,
    Button,
} from 'react-native'

import ImagePicker from 'react-native-image-crop-picker';

export class PicScreen extends Component{
    static navigationOptions = {
        header: null,   //去除页面中顶部的空白导航栏
    };
    constructor() {
        super();
        this.state = {
        }
    }

    pic(){
        // ImagePicker.openPicker({         //选择照片
        //     width: 300,
        //     height: 400,
        //     cropping: true,
        // }).then(image => {
        //     console.log(' 图片路径:'+ image);
        // });

        ImagePicker.openCamera({            //启动相机拍照
            width: 300,
            height: 400,
            cropping: false             //是否打开剪裁
        }).then(image => {
            console.log(image);
        });
    }

    render(){
        return(
            <View style={{flex:1,justifyContent:'center',alignItems:'center'}}>
                <Text style={{fontSize:24,color:'red'}}>图片选择</Text>

                <View style={{marginTop:20}}>

                    <Button
                        title="选择图片"
                        onPress={() => this.pic()}
                    />
                </View>
            </View>
        )
    }
}

 

 

参考博客:https://blog.csdn.net/u013718120/article/details/72781285

                  https://www.jianshu.com/p/8420b08062c7

github:https://github.com/ivpusic/react-native-image-crop-picker

 

react-native-image-zoom-viewer

前言:项目中经常需要点击一张图片或者一组图片来查看大图,react-native-image-zoom-viewer就是一个非常好用的第三方库。

一、安装:

yarn add react-native-image-zoom-viewer(npm i react-native-image-zoom-viewer --save)

 

参考博客:https://www.jianshu.com/p/3137f0e56d68

                  https://blog.csdn.net/sinat_17775997/article/details/74971315

github:https://github.com/magicwing/react-native-image-zoom-viewer

 

react-native-image-crop-picker 和 react-native-image-zoom-viewer综合使用:

代码(有些样式没有):

imageList.js  ===>>> 组件主文件

import React, {Component} from "react";
import {
    View,
    Text,
    // Button,
    Image,
    TouchableOpacity,
    Dimensions,
    StatusBar,
    Animated,
    Platform,
    Modal,
} from 'react-native';
import {
    Container,
    Header,
    Title,
    Content,
    Footer,
    FooterTab,
    Button,
    Left,
    Right,
    Body,
    Icon,
    Form,
    Item,
    Picker,
    Input,
    Label,
    Radio,
    H1,
    Thumbnail,
    List,
    ListItem,
    // Text,
    CheckBox
} from 'native-base';
import ImagePicker from 'react-native-image-crop-picker';
import R from 'ramda';

import {ImageBrowser} from "./imageBrowser";
import {SquareView} from "./squareView";
import {config} from "../../config";
import {_noPadding,_noMargin} from "../common";

export class ImageList extends Component {
    constructor() {
        super();

        this.state = {
            show: false,
            index: 0,
            shareModalVisible: false,
            modalAnimatedValue: new Animated.Value(0),
        };
    }
    onAdd(){
        this.setState({shareModalVisible: true,});
        Animated.timing(this.state.modalAnimatedValue, {
            toValue: 1,
            duration: 200
        }).start();
    }


    renderItem(its, index) {
        const {edit, onAdd, onDel} = this.props;
        const blankButton = (
            <SquareView layout='row' style={{flex: 1, margin: 2, flexDirection: 'column',}}>
            </SquareView>
        );
        const addButton = (
            <SquareView layout='row' style={{flex: 1, margin: 2, flexDirection: 'column',}}>
                <Button transparent
                        onPress={this.onAdd.bind(this)}
                        style={{..._noPadding, ..._noMargin, flex: 1, justifyContent: 'center', alignSelf: 'stretch', borderStyle: 'dashed', borderWidth: 1, borderColor: '#BDBEBF',}}>
                    <Icon name='add' style={{color: '#BDBEBF', fontSize: config.FONT_SIZE_CONTENT_TEXT * 3,}}/>
                </Button>
            </SquareView>
        );
        const delButton = index => {
            return edit ? (
                <Button transparent
                        onPress={() => onDel(index)}
                        style={{..._noPadding, ..._noMargin, position: 'absolute', padding: 9, top: 0, right: -10,}}>
                    <Icon name="close" style={{alignSelf: 'flex-start', color: '#e1e1e1', fontSize: config.FONT_SIZE_CONTENT_TEXT * 1.5,}}/>
                </Button>
            ) : null;
        };
        const imgButtn = (source, index) => {
            return (
                <SquareView layout='row' style={{flex: 1, margin: 2, flexDirection: 'column',}}>
                    <Button transparent
                            onPress={() => this.onBrowserOpen(index)}
                            style={{..._noPadding, ..._noMargin, flex: 1, flexDirection: 'row', alignSelf: 'stretch',}}>
                        <Image resizeMode='cover' source={source} style={{flex: 1,alignSelf: 'stretch'}}/>
                    </Button>
                    {delButton(index)}
                </SquareView>
            );
        };

        const item = its[index];
        if (item) {
            const {key} = item;
            switch (key) {
                case 'add':
                    return addButton;
                default:
                    return imgButtn(item, index);
            }
        }
        return blankButton;
    }

    render(){
        const {edit, items} = this.props;
        const {show, index} = this.state;
        let its = items;
        // 如果是编辑状态&&在最大个数内,先补上添加按钮
        if (edit && items.length < 3 * 2) {
            its = [...items, {key: 'add',}];
        }
        let vs = [];
        for (let i = 0; i < its.length; i += 3) {
            vs = [...vs, (
                <View key={i} style={{flexDirection: 'row'}}>
                    {this.renderItem(its, i)}
                    {this.renderItem(its, i + 1)}
                    {this.renderItem(its, i + 2)}
                </View>
            )];
        }
        return (
            <View style={{flex:1, margin: 8, alignItems: 'center', justifyContent: 'center',}}>
                {vs}

                <ImageBrowser ref={browser => this.browser = browser}
                              show={show}
                              index={index}
                              onClose={() => this.onBrowserClose()}
                              images={items.map(item => ({...item, url: item.uri}))}
                              saveToLocalByLongPress={false}/>

                <Modal animationType="fade"
                       visible={this.state.shareModalVisible}
                       transparent={true}
                       onRequestClose={()=>{}}
                >
                    {this._renderShareView()}
                </Modal>
            </View>
        );

    }

    onBrowserOpen(index) {
        this.setState({show: true, index});
    }

    onBrowserClose() {
        this.setState({show: false});
    }

    onMenu(type){
        switch (type) {
            case 'camera':
                ImagePicker.openCamera({
                    // width: 300,
                    // height: 400,
                    // compressImageMaxWidth: 1440,
                    // compressImageMaxHeight: 2560,
                    // compressImageQuality: 0.8,
                    compressImageMaxWidth:1024,
                    compressImageMaxHeight:1024,
                    cropping: false,
                }).then(this.onImage.bind(this));
                break;
            case 'gallery':
                ImagePicker.openPicker({
                    // width: 300,
                    // height: 400,
                    compressImageMaxWidth:1024,
                    compressImageMaxHeight:1024,
                    cropping: false,
                }).then(this.onImage.bind(this));
                break;
        }
    }

    onImage(image){
        this.setState({ shareModalVisible: false });
        this.state.modalAnimatedValue.setValue(0);

        const {onAdd} = this.props;
        if (R.is(Function)(onAdd)) {
            onAdd(image);
        }
    }

    _renderShareView() {
        const {width, height} = Dimensions.get('window');
        const itemWidth = width;//(width - 15 * 2) / 5;
        const itemHeight = 44;//(height * 0.45 - 50 - 48) / 2;
        const logoWidth = itemWidth * 0.6;
        const statusHeight = Platform.select({ios: 0, android: StatusBar.currentHeight});

        return (
            <View style={{width: width, height: height,}}>
                <TouchableOpacity
                    activeOpacity={1}
                    style={{width: width, flex: 5.5}}
                    onPress={() => {
                        this.setState({shareModalVisible: false})
                        this.state.modalAnimatedValue.setValue(0)
                    }}
                >
                    <Animated.View
                        style={{backgroundColor: 'rgba(0, 0, 0, 0.65)', width: width, flex: 1, opacity: this.state.modalAnimatedValue}}/>
                </TouchableOpacity>
                <Animated.View
                    style={{
                        backgroundColor: '#444',
                        width: width,
                        height: height * 0.4,
                        paddingHorizontal: 15,
                        position: 'absolute',
                        top: this.state.modalAnimatedValue.interpolate({
                            inputRange: [0, 1],
                            outputRange: [height, height * 0.6 - statusHeight]
                        })
                    }}
                >
                    <View
                        style={{flexDirection: 'row', justifyContent: 'center', alignItems: 'center', height: 50, borderBottomWidth: 1, borderColor: '#555'}}>
                        <Text style={{color: '#bbb', fontSize: 14, marginLeft: 5}}>添加照片</Text>
                    </View>

                    <View style={{flexDirection: 'column', flex: 1, paddingVertical: 19,}}>
                        {[{title: '拍照', type: 'camera',}, {title: '从相册选择', type: 'gallery',}].map(menu => {
                            return (
                                <TouchableOpacity
                                    key={`imagelist-${menu.type}`}
                                    activeOpacity={0.75}
                                    style={{flex: 1, height: itemHeight, justifyContent: 'center', alignItems: 'center'}}
                                    onPress={() => this.onMenu(menu.type)}
                                >
                                    {/*<Image style={{width: logoWidth, height: logoWidth}} source={channel.logo}/>*/}
                                    <Text style={{fontSize: 14, color: '#fff',}}>{menu.title}</Text>
                                </TouchableOpacity>
                            )
                        })}
                    </View>
                    <TouchableOpacity
                        activeOpacity={0.75}
                        style={{width: width, marginLeft: -15, borderTopWidth: 1, borderColor: '#777', height: 48, justifyContent: 'center', alignItems: 'center'}}
                        onPress={() => {
                            this.setState({shareModalVisible: false});
                            this.state.modalAnimatedValue.setValue(0)
                        }}
                    >
                        <Text style={{fontSize: 14, color: '#ccc',}}>取消</Text>
                    </TouchableOpacity>
                </Animated.View>
            </View>
        )
    }
}

squareView.js  ===>>>  针对主文件封装的类View组件

/**
 * Created by sysssc on 2017/5/31.
 */
import React, {Component} from "react";
import {
    Alert,
    View,
    Text,
    TextInput,
    // Button,
    TouchableOpacity,
    Switch,
} from "react-native";
import {
    Container,
    Header,
    Title,
    Content,
    Footer,
    FooterTab,
    Button,
    Left,
    Right,
    Body,
    Icon,
    Form,
    Item,
    Input,
    Label,
    H1,
    ListItem,
    // Text,
    CheckBox
} from 'native-base';

export class SquareView extends Component {
    constructor() {
        super();

        this.state = {
            width: 0,
            height: 0,
            direction: 'row' // 'column' and 'row'
        };
    }

    render() {
        const square = (
            <View
                {...this.props}
                style={
                    [this.props.style,
                        {width: this.state.width, height: this.state.height}]
                }
                onLayout={event => {
                    const {width, height} = event.nativeEvent.layout;
                    switch (this.props.layout) {
                        case 'column':
                            if (this.state.height !== height) {
                                this.setState({width: height, height: height});
                            }
                            break;
                        case 'row':
                            if (this.state.width !== width) {
                                this.setState({width: width, height: width});
                            }
                            break;
                    }
                }}>
                {this.props.children}
            </View>
        );
        return square;
    }
}

imageBrowser.js  ===>>>  点击图片放大组件

/**
 * Created by sysssc on 2017/6/7.
 */
import React, {Component} from 'react';
import {
    AppRegistry,
    StyleSheet,
    Text,
    View,
    Modal
} from 'react-native';
import {
    Container,
    Header,
    Title,
    Content,
    Footer,
    FooterTab,
    Button,
    Left,
    Right,
    Body,
    Icon,
    Form,
    Item,
    Picker,
    Input,
    Label,
    Radio,
    H1,
    Thumbnail,
    List,
    ListItem,
    // Text,
    CheckBox
} from 'native-base';

import ImageViewer from 'react-native-image-zoom-viewer';

export class ImageBrowser extends Component {
    render() {
        const {show, onClose, images, index, saveToLocalByLongPress} = this.props;
        return (
            <Modal visible={show} transparent={true} animationType={'slide'} onRequestClose={()=>{}}>
                <ImageViewer imageUrls={images} index={index} saveToLocalByLongPress={!!saveToLocalByLongPress}/>
                <Button transparent style={styles.back} onPress={onClose}>
                    <Icon name='close' style={{color: '#fffa', fontSize: 38,}}/>
                </Button>
            </Modal>
        )
    }
}

const styles = {
    back: {
        position: 'absolute',
        borderRadius: 5,
        padding: 40,
        top: 28,
        right: 0,
    },
};

效果:

 

 

文章仅为本人学习过程的一个记录,仅供参考,如有问题,欢迎指出

对博客文章的参考,若原文章博主介意,请联系删除!请原谅

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值