React Native - 动态图片源

11

我试图使用map方法循环遍历SOURCE数组,但是我一直收到这个错误:

未知的命名模块:“../images/one.jpeg”

有人知道这是为什么吗? require中的文件路径肯定是正确的。

var SECTIONS = [
  {
    title: 'One',
    fileName: 'one.jpeg',
  },
  {
    title: 'Two',
    fileName: 'two.jpeg',
  },
  {
    title: 'Three',
    fileName: 'three.jpeg',
  },
  {
    title: 'Four',
    fileName: 'four.jpeg',
  },
];


{SECTIONS.map((section, i) => (
   <CategoryCard
     key={i}
     source={require(`../images/${section.fileName}`)}
     title={section.title}
   />
))}

我认为你可能给了错误的路径。 - Codesingh
5个回答

18

我认为这不可能,因为React Native需要提前知道要捆绑什么(据我所知)。但是,您可以require数组中的所有文件:

var SECTIONS = [
  {
    title: 'One',
    file: require('../images/one.jpeg'),
  },
  {
    title: 'Two',
    file: require('../images/two.jpeg'),
  },
  {
    title: 'Three',
    file: require('../images/three.jpeg'),
  },
  {
    title: 'Four',
    file: require('../images/four.jpeg'),
  },
];


{SECTIONS.map((section, i) => (
   <CategoryCard
     key={i}
     source={section.file}
     title={section.title}
   />
))}

是的,这是我能想到的另一种解决方案。看起来不是最优的,但现在它可以工作了。谢谢! - AHinson
当我使用这个时,我得到了:<?>PNG ... unexpected character <?>。它包括图像并试图将图像作为文件读取。<?>是一个无法识别的字符,而不是实际的三个字符< ? >。 - kojow7
在我身上也完美地发挥作用。谢谢你。 - Ali Raza

5

您不能使用动态链接。我找到的最好的解决方法是:

var SECTIONS = {
  One: {
    title: 'One',
    file: require('../images/one.jpeg'),
  },
  Two: {
    title: 'Two',
    file: require('../images/two.jpeg'),
  },
  Three: {
    title: 'Three',
    file: require('../images/three.jpeg'),
  },
  Four: {
    title: 'Four',
    file: require('../images/four.jpeg'),
  },
};


{SECTIONS.map((section, i) => (
   <CategoryCard
     key={i}
     source={section.file}
     title={section.title}
   />
))}

那么,您只需使用这些文件即可。如果您有某种动态图像选择,可以使用类似以下的内容。
<Image source={SECTIONS[image.type]} />

2

已经有一个可行的解决方案,虽然不建议用于大型图片,但对于(许多)小型图片完美地工作。

步骤:

  1. 将图标转换为base64字符串。
  2. 创建一个JSON文件,以文件名为键,以base64字符串为值。 (您也可以将它们存储到本地数据库中)

例如: ImageData.json

{

"icon1": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFAAAABQ.......==",
"icon2": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFAAAABQ.......=="

}

3.将JSON文件导入到需要动态加载图像的位置。

例如:

const imageData = require("./images/ImageData.json")

4:在运行时获取/生成密钥/文件名,并获取图像源。

例如:

const imageSrc = imageData[keyname]

5:在运行时动态生成图像。

例如:

<Image style={{ width: 70, height: 70, resizeMode: Image.resizeMode.contain }} source={ uri: imageSrc } />

完成了...

额外的... 编写了一个辅助 Python 脚本来自动化创建 JSON 文件。

import base64
import os

directory = os.fsencode('.')

with open('ImagesData.json', 'wb') as jsonFile:
    jsonFile.write(bytes('{', 'utf-8'))

    written = False

    for file in os.listdir(directory):
        filename = os.fsdecode(file)

        if filename.endswith('.png'):
            with open(filename, "rb") as image_file:
                if written:
                    jsonFile.write(bytes(',\n','utf-8'))
                encoded_string = base64.b64encode(image_file.read())
                jsonFile.write(bytes(('"' +filename+ '":'), 'utf-8'))
                jsonFile.write(bytes('"data:image/png;base64,', 'utf-8') + encoded_string + bytes('"', 'utf-8'))
                written = True

    jsonFile.write(bytes('}', 'utf-8'))

1. 将脚本复制到图像文件夹中并运行脚本(需要Python 3.6)。 2. 将创建一个JSON文件,其中图像名称作为键,Base64字符串作为值。 3. 将该文件复制到项目中并使用(之后可以删除图像)。 4. 如上所述使用JSON文件。

1

我曾经遇到过同样的问题,但我的情况有些不同。我有一个包含不同对象的数组,这些对象需要动态图片。我已经在映射数组,但我需要根据名称将图像与该数组匹配。这有点hacky,但这是我处理它的方式。

首先,在我的父组件中,我创建了一个函数来渲染我的对象数组的组件。我将对象数据传递到名为“object”的prop中。

在我的情况下,我知道我的数据是什么,并且我需要将相应的图像与从外部api中提取数据的对象匹配。

renderObjects() {
return this.state.objects.map(object => (
  <ObjectListDetail
    key={object.id}
    next
    props={this.props}
    object={object}
  />
));
}

在我的ObjectListDetail组件中,我创建了一个名为icons的变量,它是另一个对象数组。这一次,我创建了一个名为name的属性,它将与从父级传递给组件的对象匹配,然后有第二个键叫做source,在其中我提供了图像的路径。大致像这样。
var icons = [
{ name: "BTC", source: Images.btc },
{ name: "ETH", source: Images.eth },
{ name: "ETC", source: Images.etc },
{ name: "ZRX", source: Images.zrx },
{ name: "USDC", source: Images.usdc },
{ name: "LTC", source: Images.ltc },
{ name: "BCH", source: Images.bch },
{ name: "USD", source: Images.usd }
];

注意***我已经将所有的图片都放在一个单独的文件中,并在顶部导入了它们。

然后,我创建了一个名为imgSrc的变量,并过滤结果以匹配我传递给子组件的对象的名称。

var imgSrc = icons.filter(
icon => icon.name === props.wallet.name
)

我随后创建了一个图像组件,并在源需求中调用了过滤器的结果,并将其指向源。
  <Image source={imgSrc[0].source} />

这就是我在应用程序中实现动态图像渲染的方法。
可能这不是最好的做法,而且我还是有点新手,但我很乐意接受任何批评。

0

尝试使用直接URL在单独的浏览器中打开文件,例如:

http://<><>/imgages/one.jpg

你也可以这样做:

一个使用React显示动态图像的工作示例:

点击此处查看示例


1
这个在React Native中可行吗?这个例子是在Web浏览器中的,那是一个非常不同的东西。 - Davin Tryon

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