2017-02-10 10 views
19

W aplikacji React Native pobieram obrazy z interfejsu API o nieznanych wymiarach. Jak automatycznie skalować wysokość, jeśli znam żądaną szerokość?Wysokość obrazu w skali automatycznej z React Native

przykład:

ustawić szerokość do Dimensions.get('window').width. Jak ustawić wysokość i zachować ten sam współczynnik?

export default class MyComponent extends Component { 
    constructor(props) { 
    super(props) 
    this.state = { 
     imgUrl: 'http://someimg.com/coolstuff.jpg' 
    } 
    } 

    componentDidMount() { 
    // sets the image url to state 
    this.props.getImageFromAPi() 
    } 

    render() { 
    return (
     <View> 
     <Image 
      source={uri: this.state.imgUrl} 
      style={styles.myImg} 
     /> 
     <Text>Some description</Text> 
     </View> 
    ) 
    } 
} 

const styles = StyleSheet.create(
    myImg: { 
    width: Dimensions.get('window').width, 
    height: >>>???what goes here???<<< 
    } 
) 
+0

Zapraszamy do obejrzenia [reagować-native skalowalnej wizerunku ] (https://www.npmjs.com/package/react-native-scalable-image) –

Odpowiedz

17

Spróbuj tego:

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

export default class ScaledImage extends Component { 
    constructor(props) { 
     super(props); 
     this.state = {source: {uri: this.props.uri}}; 
    } 

    componentWillMount() { 
     Image.getSize(this.props.uri, (width, height) => { 
      if (this.props.width && !this.props.height) { 
       this.setState({width: this.props.width, height: height * (this.props.width/width)}); 
      } else if (!this.props.width && this.props.height) { 
       this.setState({width: width * (this.props.height/height), height: this.props.height}); 
      } else { 
       this.setState({width: width, height: height}); 
      } 
     }); 
    } 

    render() { 
     return (
      <Image source={this.state.source} style={{height: this.state.height, width: this.state.width}}/> 
     ); 
    } 
} 

ScaledImage.propTypes = { 
    uri: PropTypes.string.isRequired, 
    width: PropTypes.number, 
    height: PropTypes.number 
}; 

olewam URL jako rekwizyt nazywa uri. Możesz określić swój rekwizyt width jako Dimensions.get('window').width, który powinien go pokrywać.

Należy pamiętać, że będzie to również działać, jeśli wiesz, do czego ma zostać ustawiona wysokość, i musisz zmienić szerokość, aby zachować proporcje. W takim przypadku należy podać śmigło height zamiast jednego width.

+0

To działa, dziękuję bardzo. To dla mnie zaskakujące, że nie ma wbudowanej metody, aby to osiągnąć. Sądzę, że RN wciąż jest całkiem nowy. – plmok61

+0

@ plmok61 Możesz także wypróbować 'resizeMode' prop z klasy' Image' i zastosować 'flex' w swoich stylach. Początkowo próbowałem tego, ale nie podobało mi się, jak wysokość pojemnika nie byłaby zwiększana w oparciu o przeskalowanie obrazu. – TheJizel

+0

Czy dodać rzeczywistą ścieżkę do adresu URL obrazu? – Somename

1

Pierwszy spróbować i zobaczyć, czy to działa dla Ciebie: https://github.com/facebook/react-native/commit/5850165795c54b8d5de7bef9f69f6fe6b1b4763d

Jeśli nie, to można zaimplementować własną komponentu obrazu. Ale zamiast przyjmować szerokość jako rekwizyt, zastępujesz metodę onLayout, która daje pożądaną szerokość, abyś mógł obliczyć wysokość. Działa to lepiej, jeśli nie znasz szerokości i chcesz, aby RN wykonał dla ciebie układ. Wadą jest onLayout wywołana po jednym przejściu układu i renderingu. Więc możesz zauważyć, że twoje elementy poruszają się trochę.

0

maszynopis wersja @TheJizel odpowiedź z opcjonalnym style mienia i failure zwrotnego w Image.getSize:

import * as React from 'react' 
import {Image} from 'react-native' 

interface Props { 
    uri: string 
    width?: number 
    height?: number 
    style? 
} 

interface State { 
    source: {} 
    width: number 
    height: number 
} 

export default class ScaledImage extends React.Component<Props, State> { 
    constructor(props) { 
     super(props) 
     this.state = { 
      source: {uri: this.props.uri}, 
      width: 0, 
      height: 0, 
     } 
    } 

    componentWillMount() { 
     Image.getSize(this.props.uri, (width, height) => { 
      if (this.props.width && !this.props.height) { 
       this.setState({width: this.props.width, height: height * (this.props.width/width)}) 
      } else if (!this.props.width && this.props.height) { 
       this.setState({width: width * (this.props.height/height), height: this.props.height}) 
      } else { 
       this.setState({width: width, height: height}) 
      } 
     }, (error) => { 
      console.log("ScaledImage:componentWillMount:Image.getSize failed with error: ", error) 
     }) 
    } 

    render() { 
     return <Image source={this.state.source} style={[this.props.style, {height: this.state.height, width: this.state.width}]}/> 
    } 
} 

Przykład użycia:

<ScaledImage style={styles.scaledImage} uri={this.props.article.coverImageUrl} width={Dimensions.get('window').width}/>