如何在React Native中添加全屏背景图片的最佳方法

175

我想在视图中添加全屏图像,因此我编写了以下代码

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

并将样式定义为

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

那么这样的话,我应该如何找到实际的iPhone屏幕尺寸呢?

我见过一个可以访问像素密度的API,但是没有关于屏幕尺寸的信息......

有什么想法吗?


性能如何?使用 .png 或 .jpg 好吗?将壁纸图像存储在应用程序目录树内可以吗?还是最好使用其他东西?.svg 还是其他什么? - Green
@Sabito 錆兎支持乌克兰。React Native的标准对于这个问题至关重要,因此应该放在标题中。 - TylerH
28个回答

198

(这已被弃用,现在可以使用ImageBackground)

我是这样做的。主要是摆脱了静态固定尺寸。

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,
  }
};

1
是的,这就是文档中所描述的做法。https://facebook.github.io/react-native/docs/image.html#background-image-via-nesting - Daniel Steigerwald
3
请确保Image是你返回的第一个组件,即容器。起初,我错误地将Image嵌套在作为容器的View中。 - Glavin001
这可以与https://facebook.github.io/react-native/docs/tabbarios.html一起使用吗?对我来说不起作用,选项卡无法点击。 - divyenduz
7
YellowBox.js:76 中使用<Image>和子元素已经不建议使用,将来会产生错误。请重新考虑布局或使用<ImageBackground>替代。 当我在<Image>中添加内容时,就会出现这个警告,真的很烦人。 - wzso
5
这实际上已经被弃用了。请使用ImageBackground或(更好的方法)position:absolute。 - Michele
显示剩余3条评论

129
你可以在 <Image> 元素上使用 flex: 1 样式来填充整个屏幕。然后,你可以使用 Image 调整模式之一来完全填充元素中的图像:
<Image source={require('image!egg')} style={styles.backgroundImage} />

样式:

import React from 'react-native';

let { StyleSheet } = React;

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

我非常确信,您可以去掉包裹图像的<View>,这样就可以工作。


2
好的,它可以工作了。我已经将Image元素移动到最顶部,并设置其样式为backgroundImage: { justifyContent: 'center', alignItems: 'center', flex: 1, resizeMode: Image.resizeMode.contain, }。谢谢。 - talpaz
4
经过一番挣扎后,我发现最简单的方法是将 Image 组件放在一个绝对定位的 View 中,这样背景图就可以出现在屏幕上其他内容的后面了。 - vhs
3
重要更改:<Image src=...> 现在应为 <Image source=...> - Username
现在z-index被支持了,你会改变这个答案吗? - makenova
你可以使用@media查询来根据滚动更改图像吗? - Mr-Programs
显示剩余3条评论

45

注意:这个解决方案已经过时。请参考 https://facebook.github.io/react-native/docs/images.html#background-image-via-nesting

尝试这个解决方案。它得到了官方支持,我刚测试过,结果完美无缺。

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

至于将其用作背景图片,只需执行以下操作。

<Image style={styles.backgroundImage}>
  <View>
    <Text>All your stuff</Text>
  </View>
</Image>

这是官方支持的吗? - rclai
1
是的,就是这样。 - Vinod Sobale
这里使用alignSelfwidth有什么作用? - Harkirat Saluja
您正在将 <Image /> 拉伸到可用宽度,并且宽度需要为 null 才能使 'stretch' 生效。 - Vinod Sobale
请注意,在最新版本的React(0.51.0)中,图像组件无法拥有子元素。这种方法已经不再适用。 - rplankenhorn
我会检查并回复。谢谢你的关心。 - Vinod Sobale

30

2018年3月更新:使用Image已被弃用,请使用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 >

文档:https://facebook.github.io/react-native/docs/images.html#background-image-via-nesting - Joy
1
这是正确的,现在你需要使用ImageBackground,Image作为容器已经过时了。在这里,View作为容器是不必要的,你可以只使用ImageBackground作为主要容器。 - Diego Unanue

21

我尝试了几个答案,但在使用react-native版本=0.19.0的Android上都无济于事。

由于某种原因,我的样式表中的resizeMode没有正常工作?然而,在样式表中添加:

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

同时,在Image标签中我指定了resizeMode属性:

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

它完美地工作了!如上所述,您也可以使用Image.resizeMode.cover或contain。

希望这有所帮助!


16

更新至 ImageBackground

由于使用 <Image /> 作为容器已经被弃用一段时间了,所有的答案实际上都漏掉了一些重要内容。为了正确使用,请选择带有 styleimageStyle 属性的 <ImageBackground />。将所有与图像相关的样式应用于 imageStyle

例如:

<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


13

根据Braden Rockwell Napier答案,我创建了这个BackgroundImage组件。

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

某处在我的应用中的.js文件

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

12
如果你想将其用作背景图像,你需要使用在2017年6月底引入的v0.46中的新<ImageBackground>组件(链接1)。它支持嵌套,而<Image>不久将不再支持嵌套。
以下是提交摘要:
我们正在删除嵌套视图支持的组件。我们决定这样做是因为拥有此功能会使支持<Image>的固有内容大小变得不可能;因此,在过渡过程完成后,不再需要显式指定图像大小,可以从实际图像位图中推断出。 <ImageBackground>是非常简单的插入替换,通过非常简单的样式实现了此功能。如果您想放置一些东西,请使用<ImageBackground>代替<Image>

11

哦,天啊,终于找到了一个适用于 React-Native V 0.52-RC 和 native-base 的好方法:

你的内容标签应该像这样:

//==============================================================

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

你的基本样式是: //==============================================================

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

朋友们,它可以正常工作...玩得开心


嗨,我只是想确认一下ImageBackground是从哪里导入的? - Rudolph Opperman
好的,ImageBackground是我从react-native导入的,但是我无法使用with: 100%进行设置。 - Rudolph Opperman
你是否曾经遇到过这样的问题,即在Android模拟器上显示正常,但在实际设备上却无法显示? - Rudolph Opperman
抱歉回复晚了,你可以从React Native导入ImageBackground: import {ImageBackground} from 'react-native';你测试用的是哪个设备? 我在设备上没有发现任何问题。 - Ali Esfandiari
我的模拟器是 Nexus 5 规格。我的 Android 手机是 Wileyfox Swift。主要的区别在于分辨率,所以我在图像上进行了检查,似乎如果图像分辨率比您的设备高,则不会显示。我尝试使用样式使图像变小,但没有效果,所以我将图像分辨率降低,现在看起来运行良好。分辨率较低并不是问题,因为这是一个登录屏幕,上面有一些文本输入和按钮。非常感谢。 - Rudolph Opperman

8
import { ImageBackground } from "react-native";
<ImageBackground
     style={{width: '100%', height: '100%'}}
     source={require('../assets/backgroundLogin.jpg ')}> //path here inside
    <Text>React</Text>
</ImageBackground>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接