React Native 之 Image 等比例放大无丢失显示

如果有一张 20*10 的图片,要把它放入一个 40*30 的显示区域内,我们可以做到:

contain 模式,图片显示分辨率为20*10,四周都有空白;

cover模式,图片放大为 60*30,然后切成 40*30,丢失部分图片内容;

stretch 模式,图片放大为 40*30,丢失原始的宽、高比。


实现自定义组件 ImageEquallyEnlarg.js

/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 * @flow
 */

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

export default class ImageEqualEnlarge extends Component {

//ImageEqualEnlarge 组件的状态机变量是一个style,它将被用于定义显示图片的样式
  constructor(props) {
    super(props);
    this.state = {
      style:{}
    };
  }
 //声明必须要有的图片原始宽度与高度
  static propTypes = {
    originalWidth:React.PropTypes.number.isRequired,
    originalHeight:React.PropTypes.number.isRequired
  }
//此函数被挂接到组件的onLayout事件上,当组件被布局时,此函数被调用
//在此函数中计算新的宽度与高度并将其保存到组件的状态机变量中
 onImageLayout(event){
    let layout = event.nativeEvent.layout;
    if(layout.width<=this.props.originalWidth) 
      return;
    if (layout.height<=this.props.originalHeight) 
      return;
    
    let originalAspectRatio = this.props.originalWidth/this.props.originalHeight;
    let currentAspectRatio = layout.width/layout.height;

    if(originalAspectRatio===currentAspectRatio) return;

    if(originalAspectRatio > currentAspectRatio){
           let newHeight = layout.width / originalAspectRatio;
           this.setState({
            style:{
              height:newHeight,
            }
           });
           return;
    }
    let newWidth = layout.height*originalAspectRatio;
    this.setState({
      style:{
        width:newWidth,
      }
    });
  }

  render() {
    return (
      <Image
      {...this.props}
      style={[this.props.style,this.state.style]}
      onLayout ={this.onImageLayout.bind(this)}
      >
        
      </Image>
    );
  }


}


在index.android.js 调用 自定义组件 ImageEqualEnlarge  在资源本地引入 120*120 的图像

/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 * @flow
 */

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

import ImageEqualEnlarge from './ImageEqualEnlarge.js' 

export default class ViewProject extends Component {

  render() {
    return (
      <View style={styles.container}>
        <ImageEqualEnlarge style={styles.imageStyle}
         source={require('./img/logo.png')}
         originalWidth={120}
         originalHeight={120}
        >
        </ImageEqualEnlarge>
        <ImageEqualEnlarge style={styles.image2Style}
         source={require('./img/logo.png')}
         originalWidth={120}
         originalHeight={120}
        >
        </ImageEqualEnlarge>
      
      </View>
    );
  }


}



const styles = StyleSheet.create({
  container: {
    backgroundColor:'blue',
  },
  imageStyle:{
    width:200,
    height:200,
    backgroundColor:'red',
  },
    image2Style:{
    width:300,
    height:200,
    backgroundColor:'red',
  }
 
});
AppRegistry.registerComponent('ViewProject', () => ViewProject);


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值