React Native - 将图片适应包含视图,而不是整个屏幕大小

87

我试图将图片适应它们所在的视图,以便我可以拥有无缝的图像网格。问题是resizeMode='contain'似乎适合于屏幕宽度或至少某个更高级别的容器,我需要图片适应每个列表项的大小。

这里是样式和结果栅格的一个非常丑陋的示例:

样式:

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
  }
})

页面布局:

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

使用 resizeMode='contain' 的结果:

enter image description here

使用 resizeMode='cover' 的结果:

enter image description here

可以看到,使用cover的图片非常大,宽度与整个屏幕一样,并且不适合立即包含的视图。

更新1:

通过对图像应用缩放变换并从中心缩小,我能够实现接近我想要的结果:

变换如下:

transform: [{ scale: 0.55 }]

最终布局(不包括边距和填充):在此输入图片描述


1
你能否提供一个示例图像,展示你想要的外观或类似的外观?谢谢。 - Nader Dabit
嘿,@NaderDabit,我现在会更新一个例子。 - BarakChamo
所有的图片都是正方形的吗? - Nader Dabit
9个回答

124

如果你知道纵横比,例如,如果你的图像是正方形,你可以将heightwidth中的任何一个设置为填充容器,并且使用aspectRatio属性来设置另一个。

如果您希望自动设置height,则可以使用以下样式:

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

注意:height 必须是 undefined

编辑(基于 @rob-art 的评论):
如果您的图像与您在样式中想要设置的宽高比不同,您可以使用 resizeMode 控制如何显示图像。使用 resizeMode:'contain' 以确保您的图像不会被裁剪。
有关更多详细信息,请参见文档


5
这个答案有什么问题吗?对我来说好像是有效的。如果有需要我修复的地方,请评论指出。 - sazzy4o
17
我必须添加resizeMode: 'contain'才能使其正常工作。否则默认的覆盖模式会裁剪图像。 - rob-art

58

View的尺寸设置好,并确保您的图像样式中高度和宽度设置为'undefined',就像下面的示例一样:


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

这将确保您的图像缩放并完美适合您的视图。


1
这对我有效,但未定义会引起任何问题吗? - showtime

42

如果有人想让他的图像在全屏幕中适合(无论是纵向还是横向),而不需要进行任何裁剪,请使用以下代码:

``` css img { object-fit: contain; width: 100%; height: 100%; } ```
image: {
    flex: 1,
    width: '100%',
    height: '100%',
    resizeMode: 'contain',
},

17

使用ImageresizeMode属性时,我无法使示例正常工作,但因为所有图像都将是方形,所以可以使用窗口尺寸的Dimensions和flexbox来实现。

设置flexDirection: 'row'flexWrap: 'wrap',只要它们都具有相同的尺寸,它们就会排成一条直线。

我在这里设置了它

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

谢谢Nader,我使用了您的解决方案,它完美地解决了我的问题。我曾希望有一个能够使用内置的flexbox支持的东西,但是这个解决方案已经满足了我的需求。 - BarakChamo

12

简单地说,您需要像这样传递resizeMode以适应包含视图中的图像

<Image style={styles.imageStyle} resizeMode={'cover'} source={item.image}/>

const style = StyleSheet.create({
  imageStyle: {
      alignSelf: 'center',
      height:'100%', 
      width:'100%'
    },]
})

5
我认为是因为您没有为item指定宽度和高度。
如果您只想每行放2张图片,可以尝试使用以下代码而不是使用flex:
item: {
    width: '50%',
    height: '100%',
    overflow: 'hidden',
    alignItems: 'center',
    backgroundColor: 'orange',
    position: 'relative',
    margin: 10,
},

这对我有效,希望能帮到你。

5

这对我来说有效,

<Image style={styles.imageStyle} resizeMode="cover" source={imageSource} />

const styles = StyleSheet.create({
  imageStyle: {
    width: undefined,
    height: '100%',
    aspectRatio: 1,
    alignSelf: 'center',
  },
});

2
您可以使用“Resize Matters”库,该库始终修复图像缩放。
import { scale, verticalScale } from 'react-native-size-matters';

export const Component = props =>
    <Image style={{
        width: scale(30),
        height: verticalScale(50)
    }}/>;

在这里,你会感到非常高兴:https://github.com/nirsky/react-native-size-matters


0

图片具有一个名为 Style 的属性(就像大多数 react-native 组件一样),而对于 Image 的样式,有一个名为 resizeMode 的属性,它可以取值如下:contain、cover、stretch、center、repeat。

大多数情况下,如果您使用 center,它会适用于您。


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