react-native - 反应原生图像,动态需求
问题描述
我正在尝试在我的应用程序中包含动态图像。
const newVideo = {
...
iconPath: `require('../assets/images/${icon}.png')`
};
然后:
<Image
style={styles.iconStyle}
resizeMode="contain"
source={iconPath}
/>
但是,我没有看到我的图像或错误,有什么想法吗?
解决方案
您可以将图像存储在 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文件夹的项目名称。
推荐阅读
- c - LLVM:从 long double 制作 LLVMFP128Type
- javascript - nodejs如何使文件夹路径可从任何子目录全局发现
- javascript - 事件 onblur 不起作用元素 | JS
- html - 在 VueJS 表格中插入 HTML 属性
- python - .py 转换为 .exe 后 Pygame 混合器不工作
- php - 根据条件 SQL 连接两个表
- java - 请求对 edittext 的关注无法正常工作
- deep-linking - 如何在 KaiOS 中实现深度链接
- java - Switch 语句打印大小写不正确?
- ruby-on-rails - 我无法使用向导表单(多步表单)将数据(图像)保存到数据库