React Native组件只Image

不管在Android还是在ios原生的开发中,图片都是作为控件给出来的,在RN中也有这么一个控件(Image)。根据官网的资料,图片分为本地静态图片,网络图片和混合app资源。一下分类介绍来源官网。

静态图片资源

从0.14版本开始,React Native提供了一个统一的方式来管理iOS和Android应用中的图片。要往App中添加一个静态图片,只需把图片文件放在代码文件夹中某处,然后像下面这样去引用它:

<Image source={require('./my-icon.png')} />

图片文件的查找会和JS模块的查找方式一样。在上面的这个例子里,是哪个组件引用了这个图片,Packager就会去这个组件所在的文件夹下查找my-icon.png。并且,如果你有my-icon.ios.png和my-icon.android.png,Packager就会根据平台而选择不同的文件。二对于ios还可能有2倍图和3倍图的区分。

├── button.js
└── img
    ├── check@2x.png
    └── check@3x.png

Packager会打包所有的图片并且依据屏幕精度提供对应的资源。譬如说,iPhone 5s会使用check@2x.png,而Nexus 5上则会使用check@3x.png。如果没有图片恰好满足屏幕分辨率,则会自动选中最接近的一个图片。

注意:为了使新的图片资源机制正常工作,require中的图片名字必须是一个静态字符串。

// 正确
<Image source={require('./my-icon.png')} />

// 错误
var icon = this.props.active ? 'my-icon-active' : 'my-icon-inactive';
<Image source={require('./' + icon + '.png')} />

// 正确
var icon = this.props.active ? require('./my-icon-active.png') : require('./my-icon-inactive.png');
<Image source={icon} />

混合App的图片资源

如果你在编写一个混合App,也可以使用已经打包到App中的图片资源,系统会自动检索。

<Image source={{uri: 'app_icon'}} style={{width: 40, height: 40}} />

网络图片

在原生开发中,我们往往会去加载服务器的图片,在Rn也是支持的,我们只需要提供图片的链接和大小,没办法做到自适应。

// 正确
<Image source={{uri: 'https://facebook.github.io/react/img/logo_og.png'}}
       style={{width: 400, height: 400}} />

// 错误
<Image source={{uri: 'https://facebook.github.io/react/img/logo_og.png'}} />

加载本地图库图片

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

static saveImageWithTag(tag)   保存一个图片到相册。

@param {string} tag 在安卓上,本参数是一个本地URI,例如"file:///sdcard/img.png". 在iOS设备上可能是以下之一: 本地URI 资源库的标签 非以上两种类型,表示图片数据将会存储在内存中(并且在本进程持续的时候一直会占用内存)。 返回一个Promise,操作成功时返回新的URI。

static getPhotos(params: object) 获取图片

返回一个带有图片标识符对象的Promise。返回的对象的结构参见getPhotosReturnChecker。 @param {object} 要求的参数结构参见getPhotosParamChecker. 返回一个Promise,操作成功时返回符合getPhotosReturnChecker结构的对象。

不过网上提供了第三方的组件react-native-image-picker,这个组件同时支持photo和video,也就是照片和视频都可以用。我们使用npm安装这个组件:

npm install --save react-native-image-picker

典型使用方法

import ImagePickerManager from 'NativeModules';
 
 当你想展示相机还是相册这个选择器时:(变量options还有其它的设置,一些使用它的默认值就可以满足我们的要求,以下是我使用到的)
var options = {
  title: 'Select Avatar', // 选择器的标题,可以设置为空来不显示标题
  cancelButtonTitle: 'Cancel',
  takePhotoButtonTitle: 'Take Photo...', // 调取摄像头的按钮,可以设置为空使用户不可选择拍照
  chooseFromLibraryButtonTitle: 'Choose from Library...', // 调取相册的按钮,可以设置为空使用户不可选择相册照片
  customButtons: {
    'Choose Photo from Facebook': 'fb', // [按钮文字] : [当选择这个按钮时返回的字符串]
  },
  mediaType: 'photo', // 'photo' or 'video'
  videoQuality: 'high', // 'low', 'medium', or 'high'
  durationLimit: 10, // video recording max time in seconds
  maxWidth: 100, // photos only默认为手机屏幕的宽,高与宽一样,为正方形照片
  maxHeight: 100, // photos only
  allowsEditing: false, // 当用户选择过照片之后是否允许再次编辑图片
};
 
ImagePickerManager.showImagePicker(options, (response) => {
  console.log('Response = ', response);

  if (response.didCancel) {
    console.log('User cancelled image picker');
  }
  else if (response.error) {
    console.log('ImagePickerManager Error: ', response.error);
  }
  else if (response.customButton) {
    // 这是当用户选择customButtons自定义的按钮时,才执行
    console.log('User tapped custom button: ', response.customButton);
  }
  else {
    // You can display the image using either data:

    if (Platform.OS === 'android') {
        source = {uri: response.uri, isStatic: true};
    } else {
        source = {
            uri: response.uri.replace('file://', ''),
            isStatic: true
        };
    }

    this.setState({
      avatarSource: source
    });
  }
});

显示图片:

<Image source={this.state.avatarSource} style={styles.uploadAvatar} />

如果我们只想直接打开相册或者相机。

// Launch Camera:
  ImagePickerManager.ImagePickerManager.launchCamera(options, (response)  => {
    // Same code as in above section!
  });

  // Open Image Library:
  ImagePickerManager.ImagePickerManager.launchImageLibrary(options, (response)  => {
    // Same code as in above section!
  });

复杂功能介绍

我们现在有个需求,就是实现GridView网格的效果,那么怎么做呢?Rn是没有直接给我提供Grid控件的,但是有ListView控件,这里我们就需要自己去计算了(我们设置了 图片的)。

import React, { Component } from 'react';
import {
  AppRegistry,
  StyleSheet,
  Text,
  View,
  Image
} from 'react-native';

// 导入JSON数据
var productData = require('./productData.json');
var Dimensions = require('Dimensions');
var screenW = Dimensions.get('window').width;

// 定义一些全局的变量
var cols = 3;
var boxW = 100;
var vMargin = (screenW - cols * boxW) / (cols + 1);
var hMargin = 20;

class ImageDemo extends Component {
  render() {
    return (
      <View style={styles.container}>
        {/*返回商品列表*/}
        {this.renderAllProduct()}
      </View>
    );
  }

  // 返回商品列表
  renderAllProduct() {
    // 定义数组装所有子组件
    var allProduct = [];
    console.log(productData.data.length);
    // 遍历json数据
    for(var i=0;i<productData.data.length;i++){
      // 取出单个商品数据对象
      var product = productData.data[i];
      // 装入数组
      allProduct.push(
          <View key={i} style={styles.outViewStyle}>
            <Image source={{uri:product.icon}} style={styles.iconStyle}/>
            <Text style={styles.nameStyle}>{product.name}</Text>
          </View>
      );
    }

    // 最后要返回数组
    return allProduct;
  }

}



const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#F5FCFF',
    marginTop:20,
    // 设置主轴的方向
    flexDirection:'row',
    // 换行显示
    flexWrap:'wrap'
  },
  outViewStyle:{
    backgroundColor:'grey',
    // 设置侧轴对齐方式
    alignItems:'center',
    width:boxW,
    height:boxW,
    marginLeft:vMargin,
    marginBottom:hMargin
  },
  iconStyle:{
    width:80,
    height:80
  },
  nameStyle:{
    alignItems:'center',
    // 文字颜色
    color:"#fff"
  }
});

AppRegistry.registerComponent('ImageDemo', () => ImageDemo);

json数据

{
  "data": [
    {"icon":"1.jpg", "name":"名称一"},
    {"icon":"2.jpg", "name":"名称二"},
    {"icon":"3.jpg", "name":"名称三"},
    {"icon":"4.jpg", "name":"名称四"},
    {"icon":"5.jpg", "name":"名称五"},
    {"icon":"6.jpg", "name":"名称六"}
  ]
}

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏猿人谷

Cocoa编程中视图控制器与视图类详解

iPhone编程规则是:一个窗口,多个视图。UIView是iPhone屏幕上很多控件的基础类。每个iPhone用户界面都是由显示在UIWindow(这其实也是个...

25150
来自专栏分享达人秀

日历视图CalendarView和定时器Chronometer

上一期学习了AnalogClock、DigitalClock和TextClock时钟组件,本期继续来学习日历视图CalendarView和定时器Chro...

24060
来自专栏Windows Community

Windows 8.1 应用再出发 - 几种更新的控件

Windows 8.1 除了新增了很多很有用的控件外,还对一些控件做出了更新。接下来我们一起对这些更新的控件一一做出讲解。 1. FlipView 更新 翻转视...

37580
来自专栏十月梦想

vue非父子通讯(BUS/总线机制/订阅者模式)

前面我们讲述的是父子间的数据通讯,那么这里就来介绍非父子间通讯!之前的发布的《一天带你入门到放弃vue.js(二)》中介绍了使用Event调度器来实现传递,这里...

33410
来自专栏河湾欢儿的专栏

开发调试工具

常用的开发工具 文本编辑器:(轻量级) sublime notepad++ editplus IDE(集成开发环境 功能强大) webstrom ...

20420
来自专栏施炯的IoT开发专栏

《101 Windows Phone 7 Apps》读书笔记-Alphabet Flashcards

课程内容 Ø 幻灯片效果的切换     最近有人问我如何来写一个幻灯片的应用程序,在这个应用程序中,他们可以在不同的页面之间切换,就像在Pictures h...

21460
来自专栏Web行业观察

你真的了解回流和重绘吗?(面试必问)

回流和重绘可以说是每一个web开发者都经常听到的两个词语,我也不例外,可是我之前一直不是很清楚这两步具体做了什么事情。最近由于部门内部要做分享,所以对其进行了一...

22340
来自专栏欧阳大哥的轮子

iOS的一种基于服务器下发的动态布局方案(一)

栅格布局MyGridLayout是MyLayout布局体系里面的第八种布局。这是一种将布局约束设置和视图分离的布局方式,就像HTML中的标签元素和css样式可以...

26630
来自专栏逸鹏说道

06.移动先行之谁主沉浮----我的代码我来写(Xaml的优势)

如果移动方向有任何问题请参考===> 异常处理汇总-移动系列(点) 前面几节课,我们都是在前台创建对象,进行一些设置,那么我们为什么不用传统的方法来编程呢? 我...

27250
来自专栏游戏杂谈

AS3给图片加水印文字

通过FileReference获取选中的图片,调用它的load方法,将图片存入到内存中。使用Loader(flash.display.Loader)类的loa...

11220

扫码关注云+社区

领取腾讯云代金券