从本地资产动态渲染图像

问题描述 投票:0回答:1

我在显示本地资产文件夹中的本地资产时遇到问题。结构应该如下:

资产文件夹:

/-----/assets/doctor-images 
      screen/DashboardScreen.tsx

目前,我正在使用平面列表来显示数组中的数据,如下所示:

const DATA = [
  {
    id: "bd7acbea-c1b1-46c2-aed5-3ad53abb28ba",
    speciality: "Cardiology",
    title: "Dr. Bellamy N",
    distance: "12 mins",
  },
  {
    id: "3ac68afc-c605-48d3-a4f8-fbd91aa97f63",
    speciality: "Cardiology",
    title: "Dr. Mensah T",
    distance: "30 mins",
  },
  {
    id: "58694a0f-3da1-471f-bd96-145571e29d72",
    speciality: "Cardiology",
    title: "Dr. Klimisch J",
    distance: "70 mins",
  },
  {
    id: "1448f961-3b5d-4d81-895e-aac96aefdbed",
    speciality: "Cardiology",
    title: "Dr. Klimisch J",
    distance: "70 mins",
  },
  {
    id: "3aa28493-2173-4082-bc6f-78a1d9d0c689",
    speciality: "Cardiology",
    title: "Dr. Klimisch J",
    distance: "70 mins",
  },
  {
    id: "20ce3cd5-55b4-424c-a46a-1555bf625dbc",
    speciality: "Cardiology",
    title: "Dr. Klimisch J",
    distance: "70 mins",
  },
];

我的理想是当平面列表遍历列表时,它将具有它试图渲染的块的 ID。然后我将获取该 id 并尝试有条件地渲染 Image 组件。与 id 匹配的是 file-name.png。到目前为止,我已经做到了。

要显示的项目是平面列表:

const Item = ({title, speciality, distance, id}: ItemProps) => {
  let imageUrl = "";

  RNFS.readFile(`${id}.png`, "base64").then(res => {
    imageUrl = res;
  });

  console.log("imageUrl" + imageUrl);
  return (
    <View style={styles.item}>
      <Image source={{uri: imageUrl}} style={{width: 50, height: 50}} />;
      <Text style={styles.title}>{title}</Text>
      <Text style={styles.title}>{speciality}</Text>
      <Text style={styles.title}>{distance}</Text>
    </View>
  );
};

Flatlist代码:

<FlatList
  data={DATA}
  keyExtractor={item => item.id}
  numColumns={2}
  renderItem={({item, index}) => (
    <TouchableOpacity
      style={styles.itemContainer}
      id={index.toString()}
      onPress={() => console.log("pressed")}>
      <Item
        title={item.title}
        speciality={item.speciality}
        distance={item.distance}
        id={item.id}
      />
    </TouchableOpacity>
  )}
/>

到目前为止,我无法使用路径显示图像。我听说更好的方法是将其转换为 base64 URI 并将其放入

source
,但到目前为止运气不好。

我试过

let [imageUri, setImageUri] = useState("");
保存URI然后解码,但是当我尝试时它只会让我进入无限循环

RNFS.readFile(`${id}.png`, "base64").then(res => {
  setImageUri(`data:image/png;base64,${res}`);
});
typescript react-native
1个回答
0
投票

您的第一个问题是您的 imageUrl 应该从

useState
挂钩创建,然后在组件安装时更新;这意味着使用
useEffect
和一个空的依赖数组:

const Item = ({title, speciality, distance, id}: ItemProps) => {
  const [imageUrl,setImageUrl] = React.useState("");

  React.useEffect(()=>{
    RNFS.readFile(`${id}.png`, "base64").then(res => {
      setImageUrl(res);
   });
  },[]);

  console.log("imageUrl" + imageUrl);
  return (
    <View style={styles.item}>
      <Image source={{uri: imageUrl}} style={{width: 50, height: 50}} />;
      <Text style={styles.title}>{title}</Text>
      <Text style={styles.title}>{speciality}</Text>
      <Text style={styles.title}>{distance}</Text>
    </View>
  );
};

RNFS 使用设备的文件系统读取文件;我不认为它默认允许访问应用程序源代码中的资产文件夹;所以我认为即使现在它也会失败。好消息是,由于这些文件在您的应用程序包中,您可以使用 require 访问它们。我建议创建一个

imagesAssets.js
文件,其中的键是文件 ID,以及图像导入的值。这样做会让你的代码更加抽象,并且更容易使用 useAssets:

之类的东西预加载图像
export default {
  'bd7acbea-c1b1-46c2-aed5-3ad53abb28ba': require('./bd7acbea-c1b1-46c2-aed5-3ad53abb28ba.png'),
  '3ac68afc-c605-48d3-a4f8-fbd91aa97f63': require('./3ac68afc-c605-48d3-a4f8-fbd91aa97f63.png'),
  '58694a0f-3da1-471f-bd96-145571e29d72': require('./58694a0f-3da1-471f-bd96-145571e29d72.png'),
  '1448f961-3b5d-4d81-895e-aac96aefdbed': require('./1448f961-3b5d-4d81-895e-aac96aefdbed.png'),
  '3aa28493-2173-4082-bc6f-78a1d9d0c689': require('./3aa28493-2173-4082-bc6f-78a1d9d0c689.png'),
  '20ce3cd5-55b4-424c-a46a-1555bf625dbc': require('./20ce3cd5-55b4-424c-a46a-1555bf625dbc.png'),
};

现在导入 imageAssets 并使用 id 获取正确的图像:


const Item = ({title, speciality, distance, id}: ItemProps) => {
  
  return (
    <View style={styles.item}>
      <Image source={{uri: imageAssets[id]}} style={{width: 50, height: 50}} />;
      <Text style={styles.title}>{title}</Text>
      <Text style={styles.title}>{speciality}</Text>
      <Text style={styles.title}>{distance}</Text>
    </View>
  );
};

然后如果你想用

useAssets
预取:

const [assets, assetsError] = useAssets(Object.values(imageAssets))
© www.soinside.com 2019 - 2024. All rights reserved.