为图像文件反应本机使用变量

Posted

技术标签:

【中文标题】为图像文件反应本机使用变量【英文标题】:react native use variable for image file 【发布时间】:2016-02-27 16:40:20 【问题描述】:

我知道要在本机反应中使用静态图像,您需要专门对该图像进行要求,但我正在尝试根据数字加载随机图像。例如,我的目录中有 100 个名为 img1.png - img100.png 的图像。我正在尝试找出一种方法来执行以下操作

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

我知道这故意不起作用,但任何解决方法将不胜感激。

【问题讨论】:

你试过实现这个吗?只要您的图像文件路径存在,我就无法理解为什么这不起作用。从RN0.14开始,你可以直接从图片路径中获取图片,所以这个方法应该可以工作 您找到解决问题的方法了吗? 【参考方案1】:

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

[不适用于 Expo Managed]

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

除了使用 REQUIRE,我们可以将 URINative APP Assets 一起用于 android(和/或 ios)。 这里我们只讨论安卓

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

步骤

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

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

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

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

【讨论】:

【参考方案2】:

对于任何了解 react-native 野兽的人来说,这应该会有所帮助:)

我过去也访问过几个网站,但发现越来越令人沮丧。直到我读到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 />

每个人都有不同的方法来达到目的,只要选择最适合你的那个。

达曼 - 问:这个答案如何使用变量?

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

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

【讨论】:

非常感谢! 只是好奇,这是否意味着当用户点击视图时每个图像都会加载到内存中并且每次都会发生这种情况? @Aaron 不,加载和渲染是有区别的。这些图像仅在您使用它们时才会呈现(称为延迟加载)。将此视为一袋钩子。实际渲染发生在这里:&lt;Image source=Images.profile.comments /&gt; 这个方法如何使用变量?您仍在指定要加载的图像。 @bubble-cord 你说的是像“test 001”这样的键吗?在这种情况下;是的。 "test 001": "&lt;imgurl&gt;" 是一个有效的 js 对象,因此使用 images["test 001"] 获取键的值【参考方案3】:

我来到这个线程是为了寻找一种以动态方式添加图像的方法。我很快发现将变量传递给 Image -> require() 不起作用。

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

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

我创建了一个函数,它接受来自状态值的字符串,然后返回与该字符串逻辑匹配的图像。

设置

图像结构:

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 组件中,然后像这样导入图像组件:

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 让我走上了正确的道路。我希望这个答案对其他人有所帮助。 :)

【讨论】:

我认为你在这里过于复杂了。不需要imageSelect 函数。因为images 是一个简单的javascript 对象,所以您可以动态调用该对象中的键。例如&lt;Image source=Images.logos[this.state.network] /&gt;。只需确保它们的密钥与可能的网络状态匹配 :)【参考方案4】:
class ImageContainer extends Component 
   this.state =
     image:require('default-img')
   
    <View>
           <Image source=this.state.image />
    </View>

在本次讨论的上下文中,我遇到了一个想要为特定背景动态分配图像的案例。在这里我像这样改变状态

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

【讨论】:

这是一个好的开始。你能补充一下它是如何解决问题的吗?稍微描述一下你的代码的作用就好了。 内部要求,如果我必须使用动态图像,那怎么办?例如:image:require(this.index+".png") 最初 index = 1。 require 中的文本可以交换 state 或 props,注意上面例子的目的是检索本地图像,对于外部图像,即“image.png”,语法结构会改变到 【参考方案5】:

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

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

如果您想使用随机图片作为静态资源,您需要告诉您的应用捆绑该图片。您可以通过以下几种方式做到这一点:

1) 将其添加为您应用的静态资产,然后使用&lt;Image src=uri:'name_of_the_image_in_assets.png'/&gt; 引用它(here 是您可以将其添加到本机 iOS 应用的方法)

2) 静态要求所有图像。某种形式:

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

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

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

3) 使用&lt;Image src=uri:'http://i.imgur.com/random.jpg'/&gt;的网络图片

【讨论】:

如果你有一千张名为 image1.png、image2.png、image3.png 等的图片会怎么样 - require 不接受可变路径并且你不能编写循环以创建该 randomImages 数组。不会被逼写一千行吗?!如果我尝试将变量传递到 require 行,它会抱怨找不到模块。 如果列表来自api怎么办? 这解决了我的问题。我试图在函数中动态创建链接并将 require() 返回到图像源并且不断出现错误。干得好!

以上是关于为图像文件反应本机使用变量的主要内容,如果未能解决你的问题,请参考以下文章

如何在本机反应中显示相机胶卷图像文件名列表

如何在本机反应中将捕获的图像保存到应用程序文件夹?

如何使图库的内容(包括视频和图像文件)在本机反应中可滚动?

名称中的反应本机图像变量不起作用

无法在本机反应中加载静态图像

在本机反应中将图像转换为base64