• React Native学习-CameraRoll


    react-native中CameraRoll模块提供了访问本地相册的功能。

    在react版本为0.23.0的项目中,不支持Android,而且在iOS中使用CameraRoll还需要我们手动操作:

    iOS:

    1. 将RCTCameraRoll.xcodeproj添加到我们的项目中:展开项目 > Libraies  右键Libraies点击 “Add Files to ‘项目名’ ”,找到 项目文件夹/node_modules/react-native/Libraries/CameraRoll/RCTCameraRoll.xcodeproj , 添加到项目里。
    2. 我们要把libRCTCameraRoll.a这个苦添加到主项目的Link Binary With Libraries中,如下图:

    经过这样的添加我们在项目中再使用CameraRoll里边的函数就不会出错了。

    CameraRoll模块中有两个函数:saveImageWithTag()、getPhotos()。

    saveImageWithTag()

    保存一个图片到相册。

    @param {string} tag 在安卓上,本参数是一个本地URI,例如"file:///sdcard/img.png".

    在iOS设备上可能是以下之一:

    • 本地URI
    • 资源库的标签
    • 非以上两种类型,表示图片数据将会存储在内存中(并且在本进程持续的时候一直会占用内存)。

    返回一个Promise,操作成功时返回新的URI。

    示例:

    CameraRoll.saveImageWithTag(image).then(function (success) {
                Alert.alert(
                    '',
                    '保存到相册成功',
                    [
                        {text: '确定', onPress: () => console.log(success)}
    
                    ]
                )
            }, function (error) {
                Alert.alert(
                    '',
                    '保存到相册失败',
                    [
                        {text: '确定', onPress: () => console.log(error)}
    
                    ]
                )
            }
        )
    }

    获得相册中的照片。getPhotos()

    学习这个功能是在官方demo中学习的,它写成了一个可以使用的js文件CameraRollView.js,我们需要将该文件引入我们的项目中。

    CameraRollView.js文件代码:

    /**
     * The examples provided by Facebook are for non-commercial testing and
     * evaluation purposes only.
     *
     * Facebook reserves all rights not expressly granted.
     *
     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
     * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     * FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
     * FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
     * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
     * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     *
     * @providesModule CameraRollView
     * @flow
     */
    'use strict';
    
    var React = require('react');
    var ReactNative = require('react-native');
    var {
      ActivityIndicatorIOS,
      CameraRoll,
      Image,
      ListView,
      Platform,
      StyleSheet,
        TouchableOpacity,
      View,
    } = ReactNative;
    
    var groupByEveryN = require('groupByEveryN');
    var logError = require('logError');
    
    var propTypes = {
      /**
       * The group where the photos will be fetched from. Possible
       * values are 'Album', 'All', 'Event', 'Faces', 'Library', 'PhotoStream'
       * and SavedPhotos.
       */
      groupTypes: React.PropTypes.oneOf([
        'Album',
        'All',
        'Event',
        'Faces',
        'Library',
        'PhotoStream',
        'SavedPhotos',
      ]),
    
      /**
       * Number of images that will be fetched in one page.
       */
      batchSize: React.PropTypes.number,
    
      /**
       * A function that takes a single image as a parameter and renders it.
       */
      renderImage: React.PropTypes.func,
    
      /**
       * imagesPerRow: Number of images to be shown in each row.
       */
      imagesPerRow: React.PropTypes.number,
    
       /**
       * The asset type, one of 'Photos', 'Videos' or 'All'
       */
      assetType: React.PropTypes.oneOf([
        'Photos',
        'Videos',
        'All',
      ]),
    
    };
    
    var CameraRollView = React.createClass({
      propTypes: propTypes,
    
      getDefaultProps: function(): Object {
        return {
          groupTypes: 'SavedPhotos',
          batchSize: 5,
          imagesPerRow: 1,
          assetType: 'Photos',
          renderImage: function(asset) {
            var imageSize = 150;
            var imageStyle = [styles.image, { imageSize, height: imageSize}];
            return (
              <Image
                source={asset.node.image}
                style={imageStyle}
              />
            );
          },
        };
      },
    
      getInitialState: function() {
        var ds = new ListView.DataSource({rowHasChanged: this._rowHasChanged});
    
        return {
          assets: ([]: Array<Image>),
          groupTypes: this.props.groupTypes,
          lastCursor: (null : ?string),
          assetType: this.props.assetType,
          noMore: false,
          loadingMore: false,
          dataSource: ds,
        };
      },
    
      /**
       * This should be called when the image renderer is changed to tell the
       * component to re-render its assets.
       */
      rendererChanged: function() {
        var ds = new ListView.DataSource({rowHasChanged: this._rowHasChanged});
        this.state.dataSource = ds.cloneWithRows(
          groupByEveryN(this.state.assets, this.props.imagesPerRow)
        );
      },
    
      componentDidMount: function() {
        this.fetch();
      },
    
      componentWillReceiveProps: function(nextProps: {groupTypes?: string}) {
        if (this.props.groupTypes !== nextProps.groupTypes) {
          this.fetch(true);
        }
      },
    
      _fetch: function(clear?: boolean) {
        if (clear) {
          this.setState(this.getInitialState(), this.fetch);
          return;
        }
    
        var fetchParams: Object = {
          first: this.props.batchSize,
          groupTypes: this.props.groupTypes,
          assetType: this.props.assetType,
        };
        if (Platform.OS === "android") {
          // not supported in android
          delete fetchParams.groupTypes;
        }
        if (this.state.lastCursor) {
          fetchParams.after = this.state.lastCursor;
        }
    
        CameraRoll.getPhotos(fetchParams)
          .then((data) => this._appendAssets(data), (e) => logError(e));
      },
    
      /**
       * Fetches more images from the camera roll. If clear is set to true, it will
       * set the component to its initial state and re-fetch the images.
       */
      fetch: function(clear?: boolean) {
        if (!this.state.loadingMore) {
          this.setState({loadingMore: true}, () => { this._fetch(clear); });
        }
      },
    
      render: function() {
        return (
            <View style={{flexWrap: 'wrap'}}>
                  <ListView contentContainerStyle={{flex:1, flexDirection:'row',flexWrap: 'wrap', justifyContent:'center'}}
                    renderRow={this._renderRow}
                    renderFooter={this._renderFooterSpinner}
                    onEndReached={this._onEndReached}
                    style={{flex:1}}
                    dataSource={this.state.dataSource}
                  />
                </View>
        );
      },
    
      _rowHasChanged: function(r1: Array<Image>, r2: Array<Image>): boolean {
        if (r1.length !== r2.length) {
          return true;
        }
    
        for (var i = 0; i < r1.length; i++) {
          if (r1[i] !== r2[i]) {
            return true;
          }
        }
    
        return false;
      },
    
      _renderFooterSpinner: function() {
        if (!this.state.noMore) {
          return <ActivityIndicatorIOS style={styles.spinner} />;
        }
        return null;
      },
    
      // rowData is an array of images
      _renderRow: function(rowData: Array<Image>, sectionID: string, rowID: string)  {
        var images = rowData.map((image) => {
          if (image === null) {
            return null;
          }
          return this.props.renderImage(image);
        });
    
        return (
            <View>
             {images}
          </View>
        );
      },
    
      _appendAssets: function(data: Object) {
        var assets = data.edges;
        var newState: Object = { loadingMore: false };
    
        if (!data.page_info.has_next_page) {
          newState.noMore = true;
        }
    
        if (assets.length > 0) {
          newState.lastCursor = data.page_info.end_cursor;
          newState.assets = this.state.assets.concat(assets);
          newState.dataSource = this.state.dataSource.cloneWithRows(
            groupByEveryN(newState.assets, this.props.imagesPerRow)
          );
        }
    
        this.setState(newState);
      },
    
      _onEndReached: function() {
        if (!this.state.noMore) {
          this.fetch();
        }
      },
    });
    
    var styles = StyleSheet.create({
      image: {
        margin: 4,
      },
    });
    
    module.exports = CameraRollView;

    文件打开会有错误显示,只是语法不一样,这个不影响效果。

    使用方法:

    import CameraRollView from '../CameraRollView';
    
    export  default class CameraRollView extends Component {
        constructor(props) {
            super(props);
            CameraRoll.getPhotos({
                first: 21,
                assetType: 'Photos'
            }).then(function (data) {
    
            }, function (error) {
    
            })
        }
    
        _renderImage(asset) {
            var windowSize = require('Dimensions').get('window');
            return (
                <TouchableOpacity key={asset}>
                    <Image source={asset.node.image} style={{ (windowSize.width-30)/3, height: 110, margin:5}}/>
                </TouchableOpacity>
            );
        }
    
        render() {
            return (<View style={{flex:1}}>
                      <CameraRollView renderImage={this._renderImage}/>
                    </View>
            )
        }
    }
  • 相关阅读:
    [golang]text/template模板
    [golang]Go内嵌静态资源go-bindata的安装及使用
    GoCN每日新闻(2019-09-23)
    spring mvc中获取请求URL
    HBuilder搭配逍遥Android模拟器进行开发
    python 数据结构
    JDK8+Tomcat8配置https【转】
    JFinal的使用
    RESTful API 设计指南【转】
    jQuery验证控件jquery.validate.js的使用介绍
  • 原文地址:https://www.cnblogs.com/maoyazhi/p/5411759.html
Copyright © 2020-2023  润新知