web-dev-qa-db-fra.com

react-native - Ajuster l'image dans la vue contenant, pas toute la taille de l'écran

J'essaie d'adapter les images dans leurs vues contenant afin que je puisse avoir une grille transparente d'images. Le problème est que resizeMode='contain' semble correspondre à la largeur de l'écran ou au moins à un conteneur de niveau supérieur, j'ai besoin que les images s'adaptent à la taille de chaque élément de la liste.

Voici un exemple très laid des styles et de la grille résultante:

Les styles:

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: 'blue'
  },

  item: {
    flex: 1,
    overflow: 'hidden',
    alignItems: 'center',
    backgroundColor: 'orange',
    position: 'relative',
    margin: 10
  },

  image: {
    flex: 1
  }
})

La disposition:

<TouchableOpacity 
  activeOpacity={ 0.75 }
  style={ styles.item }
>
  <Image
    style={ styles.image }
    resizeMode='contain'
    source={ temp }
  /> 
</TouchableOpacity>

Le résultat (avec resizeMode='contain'):

enter image description here

Le résultat (avec resizeMode='cover'):

enter image description here

Comme vous pouvez le voir, les images covered sont très grandes et sont aussi larges que tout l'écran et ne correspondent pas à la vue contenant immédiatement.

Mise à jour 1:

J'ai pu obtenir un résultat proche de ce que je cherchais en appliquant une transformation d'échelle à l'image et en la rétrécissant par rapport au centre:

La transformation:

transform: [{ scale: 0.55 }]

La disposition résultante (sans marges ni rembourrages): enter image description here

21
BarakChamo

Je n'ai pas pu obtenir l'exemple en utilisant les propriétés resizeMode de Image, mais parce que les images seront toutes carrées, il existe un moyen de le faire en utilisant les dimensions de la fenêtre avec Flexbox.

Ensemble flexDirection: 'row', et flexWrap: 'wrap', ils s'aligneront tous tant qu'ils auront tous les mêmes dimensions.

Je l'ai installé ici

https://snack.expo.io/HkbZNqjeZ

"use strict";

var React = require("react-native");
var {
  AppRegistry,
  StyleSheet,
  Text,
  View,
  Image,
  TouchableOpacity,
  Dimensions,
  ScrollView
} = React;

var deviceWidth = Dimensions.get("window").width;
var temp = "http://thumbs.dreamstime.com/z/close-up-angry-chihuahua-growling-2-years-old-15126199.jpg";
var SampleApp = React.createClass({
  render: function() {
    var images = [];

    for (var i = 0; i < 10; i++) {
      images.Push(
        <TouchableOpacity key={i} activeOpacity={0.75} style={styles.item}>
          <Image style={styles.image} source={{ uri: temp }} />
        </TouchableOpacity>
      );
    }

    return (
      <ScrollView style={{ flex: 1 }}>
        <View style={styles.container}>
          {images}
        </View>
      </ScrollView>
    );
  }
});
7
Nader Dabit

Définissez les dimensions sur Affichage et assurez-vous que votre Image est stylisé avec une hauteur et une largeur définies sur 'non défini' comme dans l'exemple ci-dessous:

    <View style={{width: 10, height:10 }} >
      <Image style= {{flex:1 , width: undefined, height: undefined}}    
       source={require('../yourfolder/yourimage')}
        />
    </View>

Cela garantira que votre image évolue et s'intègre parfaitement dans votre vue.

21
Naadiya Ahmed

Si vous connaissez le rapport hauteur/largeur par exemple, si votre image est carrée, vous pouvez définir le height ou le width pour remplir le conteneur et obtenir que l'autre soit défini par le aspectRatio propriété

Voici le style si vous souhaitez que height soit défini automatiquement:

{
    width: '100%',
    height: undefined,
    aspectRatio: 1,
}

Remarque: height doit être undefined

14
sazzy4o

Je pense que c'est parce que vous n'avez pas spécifié la largeur et la hauteur du item.

Si vous ne voulez avoir que 2 images d'affilée, vous pouvez essayer quelque chose comme ça au lieu d'utiliser flex:

item: {
    width: '50%',
    height: '100%',
    overflow: 'hidden',
    alignItems: 'center',
    backgroundColor: 'orange',
    position: 'relative',
    margin: 10,
},

Cela fonctionne pour moi, j'espère que cela aide.

3
user3685578