React Native - 使用resizeMode“contain”实现图片垂直居中对齐

46

当图像的调整模式为“包含”时,它似乎会将实际图像在中心对齐/对齐,但图像内容却对齐/对齐于 flex 的开头。

<Image resizeMode="contain" ...>
<Text>Title</Text>
</Image>

通过以下方式,我看到文本出现在图像上方。

有没有办法将包含的图像垂直对齐到顶部?


3
你解决了这个问题吗?你的帖子是我在网上找到的唯一参考资料。谢谢你分享任何额外的信息。 - bgolson
对我来说也是同样的问题。但如果我用其他组件替换Image,那就没问题了。为什么Image这么特殊呢? - Bagusflyer
1
我认为Kyle想要的效果可以通过CSS属性background-position(https://developer.mozilla.org/en-US/docs/Web/CSS/background-position)在Web上实现。我也在寻找解决这个问题的方法。当使用cover或contain时,我并不总是希望图像在视图中垂直和水平居中。 - SomethingOn
2
FYI,React Native不支持background-position :/ - Guillaume Guillaume
这太蠢了。这是一个非常基本的要求,但 React Native 并不支持它。 - Jonas Sourlier
7个回答

11

我能够使用以下代码模拟CSS的backgroundPosition:

<View style={{ overflow: 'hidden' }}>
  <Image src={{ uri: imageURI }} style={{ height: /*adjust_as_needed*/, resizeMode: 'cover' }} />
</View>

因为在视图上使用了overflow: 'hidden',所以可以调整图片的高度而不会看到图片的额外高度。此外,您需要使用'cover'而不是'contain'作为调整模式,否则如果将图片的高度设置得太大,则会得到一个居中的图片,它不如View容器宽。

在下面的两个示例中,顶部示例中的图片高度(蓝色虚线)比底部示例更大,因此图像的中心线位于视图中更低的位置。通过减小第二个示例中的图像高度(蓝色虚线),可以使图像的中心线在视图中向上移动。

输入图片说明


9

使用resizeMethod="resize"

我找到了一个解决方案,不需要任何额外的标签或技巧,只需要一个单一的属性。

背景

由于我的远程图片@3x普通大小,一旦使用{ height: 100, width: 300, resizeMode: 'contain' }样式值在手机上加载,它会自动居中显示。

示例

为了解决这个问题,我只需添加以下属性:resizeMethod

<Image
  style={{ height: 100, width: 300, resizeMode: 'contain' }}
  source={{ uri: 'https://www.fillmurray.com/900/300' }}
  resizeMode="contain"
  resizeMethod="resize"
/>

5
不支持百分比高度/宽度,只支持硬编码数值。 - Dror Bar
据我所知,当我尝试过使用百分比时,它根本不起作用,垂直对齐问题暂且不提。 - Zachary Dahan
@ZacharyDahan 看起来这只是一个适用于Android的方法:https://reactnative.dev/docs/image#resizemethod-android - Jérémy Magrin
当我编写这段代码时,我只是在开发iOS应用程序。resizeMode="contain" 是iOS的属性,也应该能够解决问题。 - Zachary Dahan

7
您需要在图像上使用样式来设置所需的垂直对齐方式。
var SampleApp = React.createClass({
  render: function() {
    return (
      <View style={styles.container}>
        <Image source={{uri: "http://placekitten.com/300/505"}} style={styles.image}>
          <Text style={styles.instructions}>
            Hello !
            </Text>
        </Image>
      </View>
    );
  }
});

var styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'stretch',
    backgroundColor: '#F5FCFF',
  },
  image: {
    height: 500,
    justifyContent: "space-around",    //  <-- you can use "center", "flex-start",
    resizeMode: "contain",             //      "flex-end" or "space-between" here
  },
  instructions: {
    textAlign: 'center',
    color: 'white',
    backgroundColor: "transparent",
    fontSize: 25,
  },
});

请查看https://rnplay.org/apps/9D5H1Q,获取一个运行的示例。


1
你好,感谢回复。不幸的是,这并没有完全解决我面临的问题。我在https://rnplay.org/apps/9qKrYA中添加了一个示例。请注意,即使使用flex-start,实际图像仍然位于中心。 http://prntscr.com/8wc3cf - Kyle Johnson
你想要实现什么样的效果?你能在画图软件中画出来吗?你是想让图片位于行的顶部(垂直方向),并在它们下面留有白色空间吗? - Corentin S.

1

我需要做同样的事情。我发现实现这个的最好方法是明确给出图像的高度或宽度。然后,通过将您的图像包装在另一个组件中,您可以使用justifyContent来完全控制图像的位置。

确实,您可能并不总是拥有图像的宽度或高度。但是,很多时候(特别是如果使用resizeMode:'contain'),您希望将高度或宽度相对于某些东西设置。我希望高度等于视口的宽度。这是我使用的解决方案:

<View style={{ flex: 1, justifyContent: 'flex-start' }}>
    <Image
      source={{ uri: imagePath }}
      resizeMode="contain"
      style={{ height: vw(100) }}
    />
 </View>

vw是一个辅助函数,来自this的答案。


1

这很简单。首先找到屏幕的高度:

const height = Dimensions.get('window').height

现在进入您的样式属性,将marginVertical属性设置为以下值(height / 4):

<Image source = {// some url} resizeMode = 'contain' style = {width: '100%', height: height/2, marginVertical: height/4}

现在您的图像将垂直居中。


1

我刚刚遇到了同样的问题,但是建议的解决方案都对我无效。一个设置了resizeMode="contain"的图像总是居中显示,并忽略外部容器的justifyContent设置。

我通过将图像的widthheight都设置为undefined,并指定其aspectRatio来“修复”此问题:

    <View
      style={
          justifyContent: 'flex-end',
        }}
    >
      <Image
        source={require('./img/source.png')}
        style={{
          // This is as strange as it gets. The `flex-end` setting works _only_ if I pass the image's aspect ratio
          // and `undefined` for width and height properties. If any of these are missing, the image with `resizeMode="contain"
          // will be centered vertically and ignore the `justifyContent` setting of the outer container.
          aspectRatio: 0.5622, // In my case
          width: undefined,
          height: undefined,
          resizeMode: 'contain',
        }}
      />
    </View>

-1
你需要修复一些值,而其他的则保持不变。在大多数情况下,让宽度固定。要小心父级 flex 选项,它可能会改变你的设计。

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