React Native等比放大不丟失圖片

9月11號 0.33版本,resizeMode中添加了center, 能夠實現同樣的功能。不過但願這篇文章還能幫助你們。php

以前咱們學習了從零學React Native之08Image組件react

你們能夠發現, 原生的Image控件沒法實現等比放大後無丟失顯示。
如: 有一張20x10的圖片, 要放入一個40x30的顯示區域內.
1. cover模式(默認),圖片放大爲60x30, 而後切成40x30, 會丟失部分顯示的圖片。
2. contain 模式, 圖片分辨率爲20x10, 四周都有空白。
3. stretch模式, 圖片放大爲40x30, 丟失原始的寬、高比。
但咱們沒法作到將圖片放大爲40*20, 而後再顯示。接下來咱們自定義組件ImageEquallyEnlarge:android

import React, { Component } from 'react';
import {
    Image
} from 'react-native';

export default class ImageEquallyEnlarge extends Component {
    // 構造
    constructor(props) {
        super(props);
        // 初始狀態
        this.state = {
            //狀態機變量是一個style, 它將被用於定義顯示圖片的樣式
            style: {}
        };
        this.onImageLayout=this.onImageLayout.bind(this);
    }
    //此函數被掛接到組件的onLayout事件上, 當組件佈局更新時, 此函數被調用
    //此函數中計算新的寬度與高度並將其保存在組件的狀態機變量中
    //event 對應的值爲 : {nativeEvent: {layout: {x, y, width, height}}}
    onImageLayout(event) {
        let layout=event.nativeEvent.layout;//獲取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
            }
        });
    }
    // {...this.props} 是JSX語法, 意思是將ImageEquallyEnlarge組件收到的props透傳給Image組件
    render(){
        return(
            <Image {...this.props}
                style={[this.props.style,this.state.style]}
                onLayout={this.onImageLayout}
            />
        )
    }
}
//控件屬性
// 聲明必需要有的圖片原始寬度與高度
ImageEquallyEnlarge.prototype = {
    originalWidth: React.PropTypes.number.isRequired,
    originalHeight: React.PropTypes.number.isRequired
};

上面代碼,沒什麼特殊的技巧, 咱們都知道在組件開始佈局或者佈局改變的時候 就會調用組件的onLayout方法, 咱們在onLayout方法中, 獲取到了Image組件的實際寬高, 而後再根據傳遞過來圖片真實的寬高計算下組件合適的寬高, 再經過狀態機修改組件的寬高。ios

測試一下,修改index.android.js或者index.ios.js:react-native

import React, { Component } from 'react';
import {
    AppRegistry,
    StyleSheet,
    View,
    Image
} from 'react-native';
//導入自定義組件
import ImageEquallyEnlarge from './ImageEquallyEnlarge';
class AwesomeProject extends Component {
    render() {
        return (
            <View style={styles.container}>
                <ImageEquallyEnlarge
                    style={styles.imageStyle}
                    source={require('./image/big_star.png')}
                    originalHeight={70}
                    originalWidth={100}
                />
                <ImageEquallyEnlarge
                    style={styles.image2Style}
                    source={require('./image/big_star.png')}
                    originalHeight={70}
                    originalWidth={100}
                />
            </View>
        );
    }
}
const styles = StyleSheet.create({
    container: {
        backgroundColor: 'blue'
    },
    imageStyle: {
        width: 240,
        height: 360,
        backgroundColor: 'red'
    },
    image2Style: {
        width: 300,
        height: 460,
        backgroundColor: 'red'
    }
});
AppRegistry.registerComponent('AwesomeProject', () => AwesomeProject);

運行結果:微信

圖片原圖:markdown

這裏寫圖片描述
根據背景顏色就能夠看到 圖片實現了等比放大不丟失。函數

更多精彩請關注微信公衆帳號likeDev,公衆帳號名稱:愛上Android。
這裏寫圖片描述佈局

相關文章
相關標籤/搜索