【问题标题】:Could Not Find Image File in React Native在 React Native 中找不到图像文件
【发布时间】:2019-02-26 00:17:32
【问题描述】:

我已经定义了一个 React Native 类,该类旨在用一个图像引用填充“tableView”单元格,该图像引用是该类的道具输入。这是使用 FlatList 调用的。但是,当使用图像源标记指定时,此类无法在包中找到输入图像引用。只有当它是硬编码引用时才能找到它。

类定义如下:

class ListItem extends React.PureComponent {
    _onPress = () => {
        this.props.onPressItem(this.props.index);
    }

    render() {
        const item = this.props.item; 

        console.log("ChannelSelection Mix Button artwork: ", item.artwork);
        return (
          <TouchableHighlight
            onPress={this._onPress}
            underlayColor="transparent">
            <View>
              <View style={styles.rowContainer}>
                <Image source={{ uri: item.artwork }} style={styles.buttonContainer} />
                <View style={styles.mixButtonTitleContainer}>
                  <Text style={styles.mixButtonTitle}
                    numberOfLines={2}>{item.channelTitle}</Text>
                </View>
              </View>
            </View>
          </TouchableHighlight>
        );
    }
}

当调用这个类时,我收到一条警告:

Warning
Could not find image file:///Users/myname/Library/Developer/CoreSimulator/Devices/34AE8A68-E69D-4804-B3C4-96DE7A051B9B/data/Containers/Bundle/Application/C79368E9-3D1B-492C-B72B-9BF5C4D3262B/myApp.app/./Resources/MissingAlbumArt.png

打印 item.artwork 的控制台输出是:

'ChannelSelection Mix Button artwork: ', './Resources/MissingAlbumArt.png'

这样你就可以看到文件名被正确传入了。

请注意,如果我换行:

<Image source={{ uri: item.artwork }} style={styles.buttonContainer} />

到:

<Image source={require('./Resources/MissingAlbumArt.png')} style={styles.buttonContainer} />

然后错误消失。

那么,如何正确引用资源目录中的 .png 文件?为什么我的 .png 文件不在包的 Resources 目录中?

【问题讨论】:

    标签: image react-native


    【解决方案1】:

    使用带有require 的图像

    使用图像的一种方式是在捆绑包中。您可以使用

    访问这些图像
    const imageName = require('./path/to/the/image/imageName.png'); 
    

    对于我以这种方式添加的图像,我实际上创建了一个文件(称为Images.js),其中包含我的所有需求,然后导出图像。所以在文件中它将是一个这样的需求列表

    export const imageName = require('./path/to/the/image/imageName.png'); 
    

    然后当我想使用图像时,我会像这样导入图像:

    import { imageName } from '.path/to/Images.js';
    

    在设备上使用图片

    另一种方法是下载文件,然后将其保存在应用程序的文档目录中。通常您使用rn-fetch-blobreact-native-fs 将文件下载并保存到某个位置,例如文档目录。

    然后您将构建文件的路径并使用它。因此,例如,如果您使用react-native-fs,您可以按以下方式构造路径,

    let pathToImage = RNFS.DocumentDirectoryPath + '/path/to/dowloaded/file/imageName.png'
    

    你的情况发生了什么

    您正在混合使用这两种方法。当您进行开发时,图像尚未存储在您的设备上。它们当前由捆绑器提供给设备。这样你就必须使用require 方法来访问它们。当您使用它们时,它们会被复制(查看捆绑器中的日志,您会看到它正在发生)。

    当您创建您的产品ipaapk 时,所有图像和代码都会捆绑在一起并添加到应用程序中,require 语句会告诉设备在哪里可以找到该捆绑包中的图像。如果您在将文件捆绑到 ipaapk 后尝试使用该文件的路径,它将无法在开发中工作,并且您最终会遇到类似的错误。

    如果您尝试使用类似于以下路径的路径访问该文件,它将无法正常工作,因为该文件不存在,因为该文件位于捆绑包中。最好使用require 方法。

    file:///Users/myname/Library/Developer/CoreSimulator/Devices/34AE8A68-E69D-4804-B3C4-96DE7A051B9B/data/Containers/Bundle/Application/C79368E9-3D1B-492C-B72B-9BF5C4D3262B/myApp.app/./Resources/MissingAlbumArt.png 
    

    还有一点需要注意的是iOS 不能保证文件路径保持静态。如果您运行react-native run-ios,尽管应用程序已重新加载并且设备上只显示一个应用程序,但它实际上可以移动文件夹,因此最好动态构建指向您已保存到iOS 上任何目录的文件的链接。

    小吃

    这是一个小吃,显示使用Images.js 来存储文件的所有要求。 https://snack.expo.io/@andypandy/requiring-images

    这是我在这个项目中的目录结构

    ├── App.js
    ├── Images.js
    ├── README.md
    ├── app.json
    ├── assets
    │   ├── bart.png
    │   ├── lisa.png
    │   ├── maggie.png
    │   └── parents
    │       ├── homer.jpg
    │       └── marge.jpg
    ├── components
    │   ├── AssetExample.js
    │   └── SecondAssetExample.js
    └── package.json
    

    这是我在Images.js 中构造require 语句的方式

    export const MARGE = require('./assets/parents/marge.jpg');
    export const HOMER = require('./assets/parents/homer.jpg');
    export const BART = require('./assets/bart.png');
    export const MAGGIE = require('./assets/maggie.png');
    export const LISA = require('./assets/lisa.png');
    

    【讨论】:

    • 我尝试了您的想法,即为每个 .png 文件创建一个带有导出的 Images.js 文件,但出现错误。文件的行如下所示: export const MissingAlbumArt = require('./Resources/MissingAlbumArt.png');我得到的错误是“需要未知模块'694'。如果您确定该文件在那里,请尝试重新启动 Metro bundler。...”我是否按照您的建议实现了这个?
    • 您的文件路径实际上取决于您存储文件的位置,您应该确保它们是正确的。通常在向项目添加新文件时,我喜欢确保我的 Metro 捆绑器是清晰的。该错误通常是因为您添加/删除了某些内容并且它正在寻找它。清除您的cache,清理您的构建文件夹并尝试重新构建项目
    • 你可以有一个单独的目录,你只需要把正确的路径放在 require 中。我不知道您如何设置项目以及将文件放在哪里。 require 中的路径相对于 Image.js 文件所在的位置。您的导入语句应为 import { MissingAlbumArt } from './Images.js' 请注意 {} 周围的 MissingAlbumArt
    • 不,这似乎是正确的。它提供了可用于查找图像的参考。我添加了一个小吃,因此您可以看到一个示例文件夹结构,它正在工作。文件夹结构是偶然的,因为它可以是任何东西,您只需要使用正确的图像路径和导入时的正确路径Images.js
    • 我在snack 中展示了一个传递包含对图像的引用的对象的示例。看看我传递给SecondAssetExample 的内容。作为奖励,这里有一个包含 FlatList 的 snack
    猜你喜欢
    • 2017-12-19
    • 2021-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-27
    • 2021-12-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多