首页 > 解决方案 > 反应原生图像,动态需求

问题描述

我正在尝试在我的应用程序中包含动态图像。

     const newVideo = {
            ...
            iconPath: `require('../assets/images/${icon}.png')`
        };

然后:

 <Image
          style={styles.iconStyle}
          resizeMode="contain"
          source={iconPath}
        /> 

但是,我没有看到我的图像或错误,有什么想法吗?

标签: react-native

解决方案


您可以将图像存储在 ios 和 android 的相应文件夹中,然后像这样调用它们:

<Image
  source={{ uri: 'myimage' }}
/>

对于 ios,如果您使用 Xcode,请将图像放在 Images.xcassets 文件夹中。检查此链接以查看它的位置:https ://developer.apple.com/library/archive/documentation/Xcode/Reference/xcode_ref-Asset_Catalog_Format/FolderStructure.html

对于 android,您必须将它们放入:

  • android/app/src/main/res/drawable-mdpi/(x1 图像)
  • android/app/src/main/res/drawable-xhdpi/(x2 图像)
  • android/app/src/main/res/drawable-xxhdpi/(x3 图像)

请记住,没有大写字母,除了 _ 用于 android 文件没有特殊字符。您应该以与 IOS 相同的方式命名它们以避免异常。

一旦您的图像位于此文件夹中,只需再次构建,您的图像就可以{uri : "myimage"}作为源属性访问。

我制作了一个脚本来为我完成这项工作:

const sharp = require('sharp');
const fs = require('fs');

const fileImport = (file, dir = '') => {
  const filePath = dir + file;
  const imgSrc = file.replace('.png', '').replace('.jpg', '');
  const extension = file.indexOf('.png') > -1 ? 'png' : 'jpg';

  const iosPath = './ios/myproject/Images.xcassets/';
  const imgFolderExtension = '.imageset';

  const androidPathx1 = './android/app/src/main/res/drawable-mdpi/';
  const androidPathx2 = './android/app/src/main/res/drawable-xhdpi/';
  const androidPathx3 = './android/app/src/main/res/drawable-xxhdpi/';

  const jsonContentIos = `{
        "images" : [
          {
            "idiom" : "universal",
            "filename" : "${imgSrc}.${extension}",
            "scale" : "1x"
          },
          {
            "idiom" : "universal",
            "filename" : "${imgSrc}@2x.${extension}",
            "scale" : "2x"
          },
          {
            "idiom" : "universal",
            "filename" : "${imgSrc}@3x.${extension}",
            "scale" : "3x"
          }
        ],
        "info" : {
          "version" : 1,
          "author" : "xcode"
        }
      }`;

  const createImageIos = x => {
    sharp(filePath)
      .metadata()
      .then(info => {
        sharp(filePath)
          .resize(parseInt(info.width / (x === 1 ? 3 : x === 2 ? 1.5 : 1), 10))
          .toFile(
            iosPath +
              imgSrc +
              imgFolderExtension +
              '/' +
              imgSrc +
              (x === 1 ? '' : x === 2 ? '@2x' : '@3x') +
              '.' +
              extension,
            err => {
              if (err) {
                console.log(err);
              } else {
                console.log('Success iOS @x' + x);
              }
            }
          );
      });
  };

  const createImageAndroid = x => {
    sharp(filePath)
      .metadata()
      .then(info => {
        sharp(filePath)
          .resize(parseInt(info.width / (x === 1 ? 3 : x === 2 ? 1.5 : 1), 10))
          .toFile(
            (x === 1
              ? androidPathx1
              : x === 2
                ? androidPathx2
                : androidPathx3) +
              imgSrc +
              '.png',
            err => {
              if (err) {
                console.log(err);
              } else {
                console.log('Success Android @x' + x);
              }
            }
          );
      });
  };

  // Create folder of the image inside IOS Native folder
  if (!fs.existsSync(iosPath + imgSrc + imgFolderExtension)) {
    console.log('Folder created', iosPath + imgSrc + imgFolderExtension);
    fs.mkdirSync(iosPath + imgSrc + imgFolderExtension);
    // Write Contents.json
    fs.writeFile(
      iosPath + imgSrc + imgFolderExtension + '/Contents.json',
      jsonContentIos,
      'utf8',
      () => {
        console.log('Contents.json created in Ios folder');
        createImageIos(3);
        createImageIos(2);
        createImageIos(1);
        createImageAndroid(3);
        createImageAndroid(2);
        createImageAndroid(1);
      }
    );
  } else {
    console.log('Image already imported');
  }
};

const argv = process.argv[2];
if (!argv) {
  console.log('Missing argument');
  process.exit();
}

if (argv.indexOf('.png') > -1 || argv.indexOf('.jpg') > -1) {
  fileImport(argv);
} else {
  const realDir = argv.indexOf('/') > -1 ? argv : argv + '/';
  fs.readdirSync(realDir).forEach(file => {
    console.log('file', file);
    if (file.indexOf('.png') > -1 || file.indexOf('.jpg') > -1) {
      fileImport(file, realDir);
    }
  });
}

它接受一个参数,文件夹或图像。您需要安装sharp才能使其工作。( npm i sharp) 它会将您的 3x 图像转换为 2x 和 1x 并将它们复制到相应的文件夹中。不要忘记替换IOS文件夹的项目名称。


推荐阅读