将本机使用变量用于图像文件

时间:2015-11-25 01:52:24

标签: javascript ios react-native

我知道要在本机中使用静态图像,你需要专门对该图像做一个要求,但我试图根据一个数字加载一个随机图像。例如,我在我的目录中有100个名为img1.png的图像 - img100.png。我想找到一种方法来做以下

<Image source={require(`./img${Math.floor(Math.random() * 100)}.png`)}/>

我知道这有意无效,但任何变通办法都会受到高度赞赏。

5 个答案:

答案 0 :(得分:52)

对于任何了解反应本地野兽的人来说,这应该有所帮助:)

我过去也访问了几个网站,但发现它越来越令人沮丧。直到我阅读this site here

这是一种不同的方法,但它最终会得到回报。 基本上,最好的方法是将所有资源加载到一个地方。 考虑以下结构

app  
   |--img
      |--image1.jpg
      |--image2.jpg
      |--profile
          |--profile.png
          |--comments.png
      |--index.js

index.js中,您可以这样做:

const images = {
    profile: {
        profile: require('./profile/profile.png'),
        comments: require('./profile/comments.png'),
    },
    image1: require('./image1.jpg'),
    image2: require('./image2.jpg'),
};

export default images;

在您的视图中,您必须导入图像组件,如下所示:

import Images from './img/index';

render() {
    <Image source={Images.profile.comments} />
}

每个人都有不同的手段来结束,只选择最适合你的那个。

Da Man - 问:这个答案如何使用变量?

好吧,因为require只接受一个文字字符串,所以你不能使用变量,连接字符串等。这是下一个最好的事情。是的,它仍然是很多工作,但现在你可以做一些类似OP的问题:

render() {
  var images = { test100: "image100" };
  return (
    <View>
      <Text>
       test {images["test" + "100"]}
      </Text>
    </View>
  );
}

答案 1 :(得分:31)

在JS中,require语句在bundle时解析(计算JS包时)。因此,不支持将变量表达式作为require的参数。

如果需要资源,则更加棘手。当您拥有require('./someimage.png')时,React Native packager将会定位所需的图像,然后它将与应用程序捆绑在一起,以便在您的应用程序运行时它可以用作“静态”资源(事实上在开发模式下它不会将图像与您的应用程序捆绑在一起,而是从服务器提供图像,但这在您的情况下无关紧要。)

如果您想将随机图片用作静态资源,则需要告知您的应用将图片捆绑在一起。您可以通过以下几种方式实现:

1)将其添加为应用的静态资源,然后使用<Image src={{uri:'name_of_the_image_in_assets.png'}}/>引用它(here是如何将其添加到原生iOS应用中的方式)

2)静态地要求所有图像。 Sth的形式:

var randomImages = [
    require('./image1.png'),
    require('./image2.png'),
    require('./image3.png'),
    ...
];

然后在你的代码中你可以这样做:

<Image src={randomImages[Math.floor(Math.random()*randomImages.length)]}/>

3)将网络图像与<Image src={{uri:'http://i.imgur.com/random.jpg'}}/>

一起使用

答案 2 :(得分:0)

class ImageContainer extends Component {
   this.state ={
     image:require('default-img')
   }
    <View>
           <Image source={this.state.image} />
    </View>
}

在此讨论的背景下,我有一种情况是要为特定背景动态分配图像。在这里我这样改变状态

this.setState({
  image:require('new-image')
})

答案 3 :(得分:0)

我来到这个线程,寻找一种以动态方式添加图像的方法。我很快发现将变量传递给Image-> require()无效。

感谢DerpyNerd让我走上正确的道路。

在一个地方实现资源后,我发现添加图像很容易。但是,我仍然需要一种方法,可以根据应用程序中状态的变化动态分配这些图像。

我创建了一个函数,该函数将从状态值中接收字符串,然后在逻辑上返回与该字符串匹配的Image。

设置

图片结构:

app  
  |--src
    |--assets
      |--images
        |--logos
          |--small_kl_logo.png
          |--small_a1_logo.png
          |--small_kc_logo.png
          |--small_nv_logo.png
          |--small_other_logo.png

        |--index.js
    |--SearchableList.js

index.js中,我有这个:

const images = {
  logos: {
    kl: require('./logos/small_kl_logo.png'),
    a1: require('./logos/small_a1_logo.png'),
    kc: require('./logos/small_kc_logo.png'),
    nv: require('./logos/small_nv_logo.png'),
    other: require('./logos/small_other_logo.png'),
  }
};

export default images;

在我的SearchableList.js组件中,然后像这样导入Images组件:

import Images from './assets/images';

然后我在组件中创建了一个新函数imageSelect

imageSelect = network => {
  if (network === null) {
    return Images.logos.other;
  }

  const networkArray = {
    'KL': Images.logos.kl,
    'A1': Images.logos.a1,
    'KC': Images.logos.kc,
    'NV': Images.logos.nv,
    'Other': Images.logos.other,
  };

  return networkArray[network];
};

然后在我的组件render函数中,我将此新的imageSelect函数称为根据this.state.network中的值动态分配所需的图像:

render() {
  <Image source={this.imageSelect(this.state.network)} />
}

再次感谢DerpyNerd让我走上正确的道路。我希望这个答案可以帮助其他人。 :)

答案 4 :(得分:0)

如果您有大量文件,这里有一个简单且真正动态的解决方案。

[不适用于 Expo Managed]

虽然这个问题很老,但我认为这是更简单的解决方案,可能会有所帮助。但请原谅任何术语错误,如果我有任何错误,请纠正我。

代替使用 REQUIRE,我们可以将 URI原生应用资产 用于 ANDROID(和/或 iOS)。 这里我们只讨论安卓

URI 可以根据要求轻松操作,但通常它仅用于网络/远程资产,但也适用于本地和本机资产。而 require 不能用于动态文件名和目录

步骤

  1. 从包含 android/app/src/main/assetsApp.js 的目录中打开 index.js 文件夹,如果 assets 文件夹不存在,请创建一个。
  2. images 中创建一个名为 NAME 或您选择的任何 assets 的文件夹,然后将所有图像粘贴到那里。
  3. 在包含 react-native.config.jsApp.js 的主应用文件夹中创建一个名为 index.js 的文件。
  4. 将这些行添加到新的 js 文件中:

module.exports = {
  project: {
    ios: {},
    android: {},
  },
  assets: ['./assets/YOUR_FOLDER_NAME/'],
};

YOUR_FOLDER_NAME 处使用新创建的文件夹名称 images 或任何给定的 NAME

  1. 现在从主应用程序文件夹在终端中运行 npx react-native link,这将链接/添加 android 包中的资产文件夹。然后重建调试应用。
  2. 从现在开始,您可以从 react-native 应用程序中的 android/app/src/main/assets 内部访问所有文件。 例如:
<Image
   style={styles.ImageStyle}
   source={{ uri: 'asset:/YOUR_FOLDER_NAME/img' + Math.floor(Math.random() * 100) + '.png' }}
/>