React Native 矢量图标 - 动态类型

4

我正在使用不同类型的React Native矢量图标——Material和FontAwesome,具体取决于特定图标的可用性。我想创建一个通用组件,以便在整个应用程序中包装图标的使用。迄今为止,我已经完成了以下内容:

import React from 'react';
import Icon from "react-native-vector-icons/FontAwesome";
import {theme} from "../../../styles/style";

/**
 * Common reusable icon component
 * @param props
 * @returns {*}
 */
const icon = (props) => {
    return (
        <Icon
            size={theme.SIZE_ICON}
            color={theme.BACKGROUND_ICON_COLOR}
            {...props}
            style={props.style}/>
    );
};

export default icon;

这仅适用于FontAwesome,如何根据例如prop参数使其动态化,以便在需要时可以使用Material图标?注意:我不想为每种类型创建单独的组件,例如IconMaterial,IconFontAwesome等。我希望组件的名称是Icon而不考虑类型。有可能吗?

5个回答

4

您可以将一个名为iconFamily的属性传递给您的图标组件:

在您的图标组件中,您需要导入所有想要使用的字体,例如:

import IconFA from "react-native-vector-icons/FontAwesome";
import IconMA from "react-native-vector-icons/Material";

然后在Icon的渲染函数中:

  const Icon = (props) => {

  renderIcon = () => {
    if (props.iconFamily == "FA") {
      return (
        <IconFA
        size={23}
        {...props}
        style={props.style}/>
      );
   } 
   if (props.iconFamily == "MA") {
      return (
        <IconMA
        size={23}
        {...props}
        style={props.style}/>
      );
   }
  }
  return (
      renderIcon()
  )
}

当您使用自定义图标组件时,只需指定iconFamily属性即可:
 <Icon iconFamily="FA" name="home" color="green" /> 
 <Icon iconFamily="MA" name="code" color="red" />

输出结果:

output

完整的工作示例:

https://snack.expo.io/@tim1717/humiliated-hummus


2

我总是喜欢以那种方式做。 ~/components/VectorIcons.js

import AntDesign from 'react-native-vector-icons/AntDesign'
import Entypo from 'react-native-vector-icons/Entypo'
import EvilIcons from 'react-native-vector-icons/EvilIcons'
import Feather from 'react-native-vector-icons/Feather'
import FontAwesome from 'react-native-vector-icons/FontAwesome'
import FontAwesome5 from 'react-native-vector-icons/FontAwesome5'
import FontAwesome5Pro from 'react-native-vector-icons/FontAwesome5Pro'
import Fontisto from 'react-native-vector-icons/Fontisto'
import Foundation from 'react-native-vector-icons/Foundation'
import Ionicons from 'react-native-vector-icons/Ionicons'
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons'
import MaterialIcons from 'react-native-vector-icons/MaterialIcons'
import Octicons from 'react-native-vector-icons/Octicons'
import SimpleLineIcons from 'react-native-vector-icons/SimpleLineIcons'
import Zocial from 'react-native-vector-icons/Zocial'


const VectorIcon = {
  AntDesign,
  Entypo,
  EvilIcons,
  Feather,
  FontAwesome,
  FontAwesome5,
  FontAwesome5Pro,
  Fontisto,
  Foundation,
  Ionicons,
  MaterialCommunityIcons,
  MaterialIcons,
  Octicons,
  SimpleLineIcons,
  Zocial,
}

export default VectorIcon

在任何jsx中使用 ~/pages/Home/index.jsx

import VectorIcon from '../../components/VectorIcon'

return (
  <>
   // ...
   <VectorIcon.AntDesign name="home" />
   <VectorIcon.Fontisto name="clock-outline" />
  </>
)

0

这是我的图标组件,也许你可以从中得到一些灵感。

import React, { useEffect, useState } from "react";
import {
  Ionicons,
  AntDesign,
  Entypo,
  EvilIcons,
  Feather,
  FontAwesome,
  FontAwesome5,
  Fontisto,
  Foundation,
  MaterialCommunityIcons,
  MaterialIcons,
  Octicons,
  SimpleLineIcons,
  Zocial,
} from "@expo/vector-icons";

const Icon= ({ family, name, ...props }) => {
  let Family;

  switch (family) {
    case "AntDesign":
      Family = AntDesign;
      break;
    case "Entypo":
      Family = Entypo;
      break;
    case "EvilIcons":
      Family = EvilIcons;
      break;
    case "Feather":
      Family = Feather;
      break;
    case "FontAwesome":
      Family = FontAwesome;
      break;
    case "FontAwesome5":
      Family = FontAwesome5;
      break;
    case "Fontisto":
      Family = Fontisto;
      break;
    case "Foundation":
      Family = Foundation;
      break;
    case "Ionicons":
      Family = Ionicons;
      break;
    case "MaterialCommunityIcons":
      Family = MaterialCommunityIcons;
      break;
    case "MaterialIcons":
      Family = MaterialIcons;
      break;
    case "Octicons":
      Family = Octicons;
      break;
    case "SimpleLineIcons":
      Family = SimpleLineIcons;
      break;
    case "Zocial":
      Family = Zocial;
      break;
    default:
      Family = Ionicons;
  }

  return (
    <Family
      name={name ? name : "help-outline"}
      color={"#000"}
      size={20}
      {...props}
    />
  );
};

export default Icon;

而要使用它,你可以这样做。

<Icon
    family="Ionicons"
    name="add-outline"
    color={"#333"}
    size={30}
/>

我添加了默认的字体族和名称以避免错误。


0
我找到了一个很好的解决方案。 我创建了一个独立的组件,在组件中只需将图标库名称、图标名称和图标颜色作为属性传递。

import {View} from 'react-native';
import React, {FC} from 'react';
//here is the import icon libraries
import AntDesign from 'react-native-vector-icons/AntDesign';
import Entypo from 'react-native-vector-icons/Entypo';
import EvilIcons from 'react-native-vector-icons/EvilIcons';
import Feather from 'react-native-vector-icons/Feather';
import FontAwesome from 'react-native-vector-icons/FontAwesome';
import FontAwesome5 from 'react-native-vector-icons/FontAwesome5';
import Fontisto from 'react-native-vector-icons/Fontisto';
import Foundation from 'react-native-vector-icons/Foundation';
import Ionicons from 'react-native-vector-icons/Ionicons';
import MaterialIcons from 'react-native-vector-icons/MaterialIcons';
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';
import Octicons from 'react-native-vector-icons/Octicons';
import Zocial from 'react-native-vector-icons/Zocial';
import SimpleLineIcons from 'react-native-vector-icons/SimpleLineIcons';

interface myIcon {
  iconLibrary: string;
  iconName: string;
  iconColor: string;
}

const VectorIcon: FC<myIcon> = ({iconLibrary, iconName, iconColor}) => {
  return (
    <View>
      {iconLibrary === 'AntDesign' && (
        <AntDesign name={iconName} size={20} color={iconColor} />
      )}

      {iconLibrary === 'Entypo' && (
        <Entypo name={iconName} size={20} color={iconColor} />
      )}

      {iconLibrary === 'EvilIcons' && (
        <EvilIcons name={iconName} size={20} color={iconColor} />
      )}

      {iconLibrary === 'Feather' && (
        <Feather name={iconName} size={20} color={iconColor} />
      )}

      {iconLibrary === 'FontAwesome' && (
        <FontAwesome name={iconName} size={20} color={iconColor} />
      )}

      {iconLibrary === 'FontAwesome5' && (
        <FontAwesome5 name={iconName} size={20} color={iconColor} />
      )}

      {iconLibrary === 'Fontisto' && (
        <Fontisto name={iconName} size={20} color={iconColor} />
      )}

      {iconLibrary === 'Foundation' && (
        <Foundation name={iconName} size={20} color={iconColor} />
      )}

      {iconLibrary === 'Ionicons' && (
        <Ionicons name={iconName} size={20} color={iconColor} />
      )}

      {iconLibrary === 'MaterialIcons' && (
        <MaterialIcons name={iconName} size={20} color={iconColor} />
      )}

      {iconLibrary === 'MaterialCommunityIcons' && (
        <MaterialCommunityIcons name={iconName} size={20} color={iconColor} />
      )}

      {iconLibrary === 'Octicons' && (
        <Octicons name={iconName} size={20} color={iconColor} />
      )}

      {iconLibrary === 'Zocial' && (
        <Zocial name={iconName} size={20} color={iconColor} />
      )}

      {iconLibrary === 'SimpleLineIcons' && (
        <SimpleLineIcons name={iconName} size={20} color={iconColor} />
      )}
    </View>
  );
};

export default VectorIcon;

我们想要使用的地方

 <VectorIcon
          iconColor={iconColor}
          iconLibrary={iconLibrary}
          iconName={iconName}
  />


0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接