Quelle est la meilleure façon d'ajouter une image d'arrière-plan en plein écran dans React Native

149

Je voulais ajouter une image plein écran à la vue alors j'écris ce code

return (
    <View style={styles.container}>
        <Image source={require('image!egg')}  style={styles.backgroundImage}/>
    </View>
)

et défini le style comme

var styles = StyleSheet.create({
container: {
     flex: 1,
     justifyContent: 'center',
     alignItems: 'center',
     backgroundColor: '#F5FCFF',
     flexDirection: 'column',
},
     backgroundImage:{
     width:320,
     height:480,
   }
...

mais de cette façon, comment suis-je censé trouver la taille réelle de l'écran de l'iPhone?

J'ai vu une API pour accéder à la densité de pixels mais rien sur la taille de l'écran ...

Une idée?

talpaz
la source
Et les performances? Est-il acceptable d'utiliser .pngou .jpg? Est-il possible de stocker l'image de fond d'écran dans l'arborescence du répertoire des applications? Ou vaut-il mieux utiliser autre chose? .svgOu n'importe quoi?
Vert le

Réponses:

113

Vous pouvez utiliser le flex: 1style sur un <Image>élément pour qu'il remplisse tout l'écran. Vous pouvez ensuite utiliser l'un des modes de redimensionnement de l'image pour que l'image remplisse complètement l'élément:

<Image source={require('image!egg')} style={styles.backgroundImage} />

Style:

import React from 'react-native';

let { StyleSheet } = React;

let styles = StyleSheet.create({
  backgroundImage: {
    flex: 1,
    resizeMode: 'cover', // or 'stretch'
  }
});

Je suis presque sûr que vous pouvez vous débarrasser de l' <View>emballage de votre image et cela fonctionnera.

Josh
la source
1
Oui, cela fonctionne, j'ai déplacé l'élément Image comme le plus haut et défini son style comme backgroundImage:{ justifyContent: 'center', alignItems: 'center', flex: 1, resizeMode: Image.resizeMode.contain, },Merci
talpaz
4
Après avoir lutté avec cela pendant un certain temps, j'ai trouvé qu'il était plus facile d'envelopper le Imagecomposant dans une position absolue Viewpour permettre à l'image d'arrière-plan d'apparaître derrière un autre contenu à l'écran.
Josh Habdas
3
Modification importante: <Image src=...>est maintenant<Image source=...>
Nom d'utilisateur
Maintenant que z-index est pris en charge, changeriez-vous cette réponse?
makenova
C'est bien mais l'image s'étire et le défilement est activé à l'écran
Ananta Prasad
178

(Ceci est désormais obsolète, vous pouvez utiliser ImageBackground )

Voilà comment je l'ai fait. L'essentiel était de se débarrasser des tailles fixes statiques.

class ReactStrap extends React.Component {
  render() {
    return (
      <Image source={require('image!background')} style={styles.container}>
        ... Your Content ...
      </Image>
    );
  }
}

var styles = StyleSheet.create({
  container: {
    flex: 1,
    // remove width and height to override fixed static size
    width: null,
    height: null,
  }
};
oronbz
la source
1
Oui, c'est comme ça que cela devrait être fait par docs facebook.github.io/react-native/docs/…
Daniel Steigerwald
16
C'est la meilleure réponse!
Vanson Wing Leung
3
Je vous remercie! Assurez-vous que Imagevotre premier composant est renvoyé, le conteneur. Au début, j'ai accidentellement imbriqué le Imagedans un Viewqui était le conteneur.
Glavin001
6
YellowBox.js: 76 L'utilisation de <Image> avec des enfants est obsolète et sera une erreur dans un proche avenir. Veuillez reconsidérer la mise en page ou utiliser à la place <ImageBackground>. Lorsque j'ajoute du contenu à <Image>, cet avertissement apparaît. c'est vraiment agaçant.
Benjamin Wen
4
c'est en fait obsolète. Utilisez ImageBackground ou (meilleure) position: absolue
Mike
43

Remarque: cette solution est ancienne. Veuillez plutôt vous référer à https://facebook.github.io/react-native/docs/images.html#background-image-via-nesting

Essayez cette solution. Il est officiellement pris en charge. Je viens de le tester et fonctionne parfaitement.

var styles = StyleSheet.create({
  backgroundImage: {
    flex: 1,
    alignSelf: 'stretch',
    width: null,
  }
});

Et pour l'utiliser comme image d'arrière-plan, procédez comme suit.

<Image style={styles.backgroundImage}>
  <View>
    <Text>All your stuff</Text>
  </View>
</Image>
Vinod Sobale
la source
Qu'est-ce que, est-ce officiellement pris en charge?
rclai
1
Oui. C'est. facebook.github.io/react-native/docs/…
Vinod Sobale
Quelle est l'utilité de alignSelfet widthici?
Harkirat Saluja le
Vous étirez <Image /> à la largeur disponible et la largeur doit avoir une valeur nulle pour que «stretch» ​​fonctionne
Vinod Sobale
Pour info, les composants Image ne peuvent pas avoir d'enfants dans la dernière version de React (0.51.0). Cela ne fonctionne plus.
rplankenhorn
20

J'ai essayé plusieurs de ces réponses en vain pour Android en utilisant la version react-native = 0.19.0.

Pour une raison quelconque, le resizeMode dans ma feuille de style ne fonctionnait pas correctement? Cependant, lorsque Sytlesheet avait

backgroundImage: {
flex: 1,
width: null,
height: null,
}

et, dans la balise Image, j'ai spécifié le resizeMode:

<Image source={require('path/to/image.png')} style= {styles.backgroundImage} resizeMode={Image.resizeMode.sretch}>

Cela a parfaitement fonctionné! Comme mentionné ci-dessus, vous pouvez utiliser Image.resizeMode.cover ou contenir également.

J'espère que cela t'aides!

Languette
la source
16

Mise à jour de mars 2018 L'utilisation d'Image est déconseillée Utiliser ImageBackground

  <ImageBackground 
          source={{uri: 'https://images.pexels.com/photos/89432/pexels-photo-89432.jpeg?h=350&dpr=2&auto=compress&cs=tinysrgb'}}
          style={{ flex: 1,
            width: null,
            height: null,
            }}
        >
       <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
        <Text>Your Contents</Text>
       </View>

 </ImageBackground >
Hitesh Sahu
la source
1
C'est correct, vous devez maintenant utiliser ImageBackground, Image en tant que conteneur est obsolète. L'affichage en tant que conteneur n'est pas obligatoire ici, vous pouvez utiliser uniquement ImageBackground comme conteneur principal.
Diego Unanue
13

Sur la base de la réponse de Braden Rockwell Napier , j'ai créé ce composantBackgroundImage

BackgroundImage.js

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

class BackgroundImage extends Component {
  render() {
    const {source, children, style, ...props} = this.props
    return (
      <Image source={ source }
             style={ { flex: 1, width: null, height: null, ...style } }
             {...props}>
        { children }
      </Image>
    )
  }
}
BackgroundImage.propTypes = {
  source: React.PropTypes.object,
  children: React.PropTypes.object,
  style: React.PropTypes.object
}
export default BackgroundImage

someWhereInMyApp.js

 import BackgroundImage from './backgroundImage'
 ....
 <BackgroundImage source={ { uri: "https://facebook.github.io/react-native/img/header_logo.png" } }>
    <Text>Test</Text>
 </BackgroundImage>
Ryan Wu
la source
12

MISE À JOUR vers ImageBackground

Étant donné que l'utilisation en <Image />tant que conteneur est obsolète pendant un certain temps, toutes les réponses manquent en fait quelque chose d'important. Pour une utilisation correcte, choisissez <ImageBackground />avec style et imageStyle prop. Appliquer tous les styles pertinents pour l'image àimageStyle .

Par exemple:

<ImageBackground
    source={yourImage}
    style={{
      backgroundColor: '#fc0',
      width: '100%', // applied to Image
      height: '100%' 
    }}
    imageStyle={{
      resizeMode: 'contain' // works only here!
    }}
>
    <Text>Some Content</Text>
</ImageBackground>

https://github.com/facebook/react-native/blob/master/Libraries/Image/ImageBackground.js

Pawel Sas
la source
11

Si vous souhaitez l'utiliser comme image d'arrière-plan, vous devrez utiliser le nouveau <ImageBackground>composant introduit fin juin 2017 dans la v0.46. Il prend en charge l'imbrication alors que <Image>bientôt pas.

Voici le résumé du commit :

Nous supprimons la prise en charge de l'imbrication des vues dans le composant. Nous avons décidé de le faire car cette fonctionnalité rend la prise en charge intrinsinc content sizede la<Image> impossible; Ainsi, lorsque le processus de transition est terminé, il ne sera pas nécessaire de spécifier explicitement la taille de l'image, elle peut être déduite de l'image bitmap réelle.

Et c'est l'étape n ° 0.

est un remplacement instantané très simple qui implémente cette fonctionnalité via un style très simple. S'il vous plaît, utilisez à la place de si vous voulez mettre quelque chose à l'intérieur.

antoine129
la source
9

Oh mon Dieu Enfin, je trouve un excellent moyen pour React-Native V 0.52-RC et native-base:

Votre balise de contenu devrait ressembler à ceci: // ======================================== ========================

<Content contentContainerStyle={styles.container}>
    <ImageBackground
        source={require('./../assets/img/back.jpg')}
        style={styles.backgroundImage}>
        <Text>
            Some text here ...
        </Text>
    </ImageBackground>
</Content>

Et votre style essentiel est: // =========================================== =====================

container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center'
},
backgroundImage:{
    flex : 1,
    width : '100%'
}

Ça marche de bons amis ... amusez-vous

Ali Esfandiari
la source
Salut, je veux juste vous assurer que ImageBackground d'où est-il importé?
Rudolph Opperman
OK donc ImageBackground J'ai importé de react-native cependant, je ne peux pas définir avec: 100%
Rudolph Opperman
Avez-vous déjà rencontré un problème d'affichage sur l'émulateur Android mais pas sur l'appareil?
Rudolph Opperman
Désolé pour ma réponse tardive, vous pouvez importer ImageBackground depuis React Native: importez {ImageBackground} depuis 'react-native'; appareil de sorcière avez-vous testé? Je n'ai trouvé aucun problème sur l'appareil.
Ali Esfandiari
Mon émulateur était une spécification Nexus 5. Et mon androïde était Wileyfox Swift. La principale différence était la résolution, donc je l'ai vérifiée sur l'image et il semble que si la résolution de l'image est plus élevée, votre appareil ne l'affiche pas. J'ai essayé de réduire l'image avec des styles mais cela n'a pas fonctionné, j'ai donc changé la résolution de l'image plus basse et maintenant cela semble fonctionner correctement. La résolution inférieure n'était pas vraiment un problème car il s'agit d'un écran de connexion et il y a des entrées de texte et des boutons dessus. Merci beaucoup.
Rudolph Opperman
4

Depuis la version 0.14, cette méthode ne fonctionnera pas, j'ai donc créé un composant statique qui vous simplifiera la tâche. Vous pouvez simplement le coller ou le référencer en tant que composant.

Cela devrait être réutilisable et vous permettra d'ajouter des styles et des propriétés supplémentaires comme s'il s'agissait d'un <Image />composant standard

const BackgroundImage = ({ source, children, style, ...props }) => {
  return (
      <Image
        source={source}
        style={{flex: 1, width: null, height: null, ...style}}
        {...props}>
        {children}
      </Image>
  );
}

collez-le simplement et vous pourrez l'utiliser comme une image et il devrait s'adapter à la taille entière de la vue dans laquelle il se trouve (donc s'il s'agit de la vue de dessus, il remplira votre écran.

<BackgroundImage source={require('../../assets/backgrounds/palms.jpg')}>
    <Scene styles={styles} {...store} />
</BackgroundImage>

Cliquez ici pour une image de prévisualisation

Braden Rockwell Napier
la source
4
import { ImageBackground } from "react-native";
<ImageBackground
     style={{width: '100%', height: '100%'}}
     source={require('../assets/backgroundLogin.jpg ')}> //path here inside
    <Text>React</Text>
</ImageBackground>
Naved Khan
la source
3

Pour gérer ce cas d'utilisation, vous pouvez utiliser le <ImageBackground>composant, qui a les mêmes accessoires que<Image> , et y ajouter les enfants que vous souhaitez superposer.

Exemple:

return (
  <ImageBackground source={...} style={{width: '100%', height: '100%'}}>
    <Text>Inside</Text>
  </ImageBackground>
);

Pour en savoir plus: ImageBackground | Réagir natif

Notez que vous devez spécifier certains attributs de style de largeur et de hauteur.

TPM ABDULKAREEM
la source
2

Vous devez vous assurer que votre image a resizeMode = {Image.resizeMode.contain} ou {Image.resizeMode.stretch} et définir la largeur du style d'image sur null

<Image source={CharacterImage} style={{width: null,}} resizeMode={Image.resizeMode.contain}/>
Eric Kim
la source
2

La largeur et la hauteur avec la valeur null ne fonctionnent pas pour moi, alors j'ai pensé à utiliser la position haut, bas, gauche et droite et cela a fonctionné. Exemple:

bg: {
        position: 'absolute',
        top: 0,
        bottom: 0,
        left: 0,
        right: 0,
        resizeMode: 'stretch',
},

Et le JSX:

<Image style={styles.bg} source={{uri: 'IMAGE URI'}} />
dap1995
la source
2

(RN> = 0,46)

le composant ne peut pas contenir d'enfants si vous souhaitez rendre le contenu au-dessus de l'image, pensez à utiliser le positionnement absolu.

ou vous pouvez utiliser ImageBackground

import React from 'react';
import { 
  ...
  StyleSheet,
  ImageBackground,
} from 'react-native';

render() {
  return (
    
  <ImageBackground source={require('path/to/img')} style={styles.backgroundImage} >
      <View style={{flex: 1, backgroundColor: 'transparent'}} />
      <View style={{flex: 3,backgroundColor: 'transparent'}} >
  </ImageBackground>
    
  );
}

const styles = StyleSheet.create({
  backgroundImage: {
        flex: 1,
        width: null,
        height: null,
        resizeMode: 'cover'
    },
});

Hamid Reza Salimian
la source
2

Moyen le plus simple d'implémenter l'arrière-plan:

<ImageBackground style={styles.container} source={require('../../images/screen_login.jpg')}>
  <View style={styles.logoContainer}>
    <Image style={styles.logo}
      source={require('../../images/logo.png')}
    />
  </View> 
  <View style={styles.containerTextInput}>
    < LoginForm />
  </View>   
</ImageBackground>

const styles = StyleSheet.create({
  container: {
    flex: 1,
    //   backgroundColor:"#0984e3"
  },
  containerTextInput: {
    marginTop: 10,
    justifyContent: 'center'
  },

  logoContainer: {
    marginTop: 100,
    justifyContent: 'center',
    alignItems: 'center'
  },
  logo: {
    height: 150,
    width: 150
  }
});
Ahmad Sadiq
la source
2

Pour moi, cela fonctionne bien, j'ai utilisé ImageBackground pour définir l'image d'arrière-plan:

import React from 'react';
import { SafeAreaView, StyleSheet, ScrollView, View, Text, StatusBar, Image, ImageBackground } from 'react-native';
const App: () => React$Node = () => {
return (
    <>
      <StatusBar barStyle="dark-content" />
      <View style={styles.container}> 
      <ImageBackground source={require('./Assets.xcassets/AppBackGround.imageset/2x.png')} style={styles.backgroundImage}>
        <View style={styles.sectionContainer}>
              <Text style={styles.title}>Marketing at the speed of today</Text>
        </View>
      </ImageBackground>
      </View>
    </>
  );
};


const styles = StyleSheet.create({
  container: {
    flex: 1,
    fontFamily: "-apple-system, BlinkMacSystemFont Segoe UI",
    justifyContent: "center",
    alignItems: "center",
  },
  backgroundImage: {
    flex: 1,
    resizeMode: 'cover',
    height: '100%',
    width: '100%'
  },
  title:{
    color: "#9A9A9A",
    fontSize: 24,
    justifyContent: "center",
    alignItems: "center",
  },
sectionContainer: {
    marginTop: 32,
    paddingHorizontal: 24,
  },
});

export default App;
Abdul Karim Khan
la source
1

au cas où vous ne l'auriez pas encore résolu, React Native v.0.42.0 a resizeMode

<Image style={{resizeMode: 'contain'}} source={require('..img.png')} />
user7103816
la source
1
import React, { Component } from 'react';
import { Image, StyleSheet } from 'react-native';

export default class App extends Component {
  render() {
    return (
      <Image source={{uri: 'http://i.imgur.com/IGlBYaC.jpg'}} style={s.backgroundImage} />
    );
  }
}

const s = StyleSheet.create({
  backgroundImage: {
      flex: 1,
      width: null,
      height: null,
  }
});

Vous pouvez l'essayer sur: https://sketch.expo.io/B1EAShDie (de: github.com/Dorian/sketch-reactive-native-apps )

Documentation: https://facebook.github.io/react-native/docs/images.html#background-image-via-nesting

Dorian
la source
1

Vous pouvez également utiliser votre image comme conteneur:

render() {
    return (
        <Image
            source={require('./images/background.png')}
            style={styles.container}>
            <Text>
              This text will be on top of the image
            </Text>
        </Image>
    );
}


const styles = StyleSheet.create({
    container: {
        flex: 1,
        width: undefined,
        height: undefined,
        justifyContent: 'center',
        alignItems: 'center',
      },
});
Agu Dondo
la source
1

J'ai entendu parler de l'utilisation de BackgroundImage car à l'avenir, vous ne pourrez plus imbriquer la balise Image. Mais je n'ai pas pu obtenir BackgroudImage pour afficher correctement mon arrière-plan. Ce que j'ai fait, c'est d'imbriquer mon image dans une balise View et de styliser à la fois la vue extérieure et l'image. Les clés définissaient width sur null et resizeMode sur «stretch». Voici mon code:

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

export default class BasicImage extends Component {
	constructor(props) {
	  super(props);

	  this.state = {};
	}

	render() {
		return (
			<View style={styles.container}>
	      <Image 
	        source={this.props.source}
	        style={styles.backgroundImage}
	      />
      </View>
		)
	}
}

const styles = StyleSheet.create({   
		container: {
			flex: 1,
			width: null,
			height: null,
			marginBottom: 50
		},
    text: {
    		marginLeft: 5,
    		marginTop: 22,
    		fontFamily: 'fontawesome',
        color: 'black',
        fontSize: 25,
        backgroundColor: 'rgba(0,0,0,0)',
    },
		backgroundImage: {
			flex: 1,
			width: null,
			height: null,
			resizeMode: 'stretch',
		}
});

Chris Adams
la source
1

Utilisez <ImageBackground>comme déjà dit par antoine129 . L'utilisation <Image>avec des enfants est désormais obsolète.

class AwesomeClass extends React.Component {
  render() {
    return (
      <ImageBackground source={require('image!background')} style={styles.container}>
        <YourAwesomeComponent/>
      </ImageBackground>
    );
  }
}

var styles = StyleSheet.create({
  container: {
    flex: 1,
  }
};
Aung Myat Hein
la source
0

Une autre solution simple:

<Image source={require('../assets/background.png')}
      style={{position: 'absolute', zIndex: -1}}/>

<View style={{flex: 1, position: 'absolute'}}>

  {/*rest of your content*/}
</View>
Serdar Değirmenci
la source
0

J'ai résolu mon problème d'image d'arrière-plan en utilisant ce code.

import React from 'react';
import { StyleSheet, Text, View,Alert,ImageBackground } from 'react-native';

import { TextInput,Button,IconButton,Colors,Avatar } from 'react-native-paper';

class SignInScreen extends React.Component {

    state = {
       UsernameOrEmail  : '',
       Password : '',
     }
    render() {
      return (
             <ImageBackground  source={require('../assets/icons/background3.jpg')} style {styles.backgroundImage}>
              <Text>React Native App</Text>
            </ImageBackground>
          );
    }
  }


    export default SignInScreen;

    const styles = StyleSheet.create({
     backgroundImage: {
      flex: 1,
      resizeMode: 'cover', // or 'stretch'
     }
   });
Adeel Ahmed Baloch
la source
-1

ImageBackground peut avoir une limite

En fait, vous pouvez l'utiliser directement et ce n'est pas obsolète.

Si vous souhaitez ajouter une image d'arrière-plan dans React Native et souhaitez également ajouter d'autres éléments à cette image d'arrière-plan, suivez l'étape ci-dessous:

  1. Créer une vue de conteneur
  2. Créez un élément Image avec une largeur et une hauteur de 100%. ResizeMode également: 'Cover'
  3. Créez un autre élément View sous l'élément Image avec la position: 'absolue'

Voici le code que j'utilise:

import React, { Component } from 'react';
import {Text, View, Image} from 'react-native';
import Screen from '../library/ScreenSize'

export default class MenuScreen extends Component {
    static navigationOptions = {
      header: null
    }
    render() {
        return (
          <View style={{ flex: 1 }}>
            <Image
              style={{
                resizeMode: "cover",
                width: "100%",
                height: "100%",
                justifyContent: "center",
                alignItems: "center",
                opacity: 0.4
              }}
              source={require("../assets/images/menuBackgroundImage.jpg")}
            ></Image>

            <View style={{
                width: Screen.width,
                height: Screen.height * 0.55,
                position: 'absolute',
                bottom: 0}}>
                <Text style={{
                    fontSize: 48
                }}>Glad to Meet You!</Text>
            </View>
          </View>
        );
    }
}

Profitez du codage ....

Production:

Ceci est la sortie de mon code.

Chhay Rith Hy
la source