'Trying to dynamically set the Icon based on a JSON string value

I have a client config that is on a server in JSON format.

example JSON would be like { "icon" : "facebook" }

I have the widget below.

    class MySocialIcons extends StatelessWidget {

    MySocialIcons({this.icon, this.color});

    final String icon;
    final String color;

    @override
    Widget build(BuildContext context) {

    switch(icon) {
      case 'facebook': {
        return Icon(FontAwesomeIcons.facebook, color: HexColor(color));
      }
      break;

      case 'twitter': {
        return Icon(FontAwesomeIcons.twitter, color: HexColor(color));
      }
      break;

      default: {
        return Icon(FontAwesomeIcons.home, color: HexColor(color));
      }
      break;
    }
  }
}

Is there a way to not have to write 500 switch statements for 500 font awesome icons? the format is

FontAwesomeIcons.facebook where my string value "facebook" would append on the end of FontAwesomeIcons. I am looking for a way to just write whatever I want in the string and it return the correct icon widget.



Solution 1:[1]

There are two ways you can eliminate some of your code duplication.

  1. By taking the switch out and moving it into it's own function so your build method has no duplication in it.

Switch statement

 IconData getIconForName(String iconName) {
      switch(iconName) {
        case 'facebook': {
        return FontAwesomeIcons.facebook;
        }
        break;

        case 'twitter': {
          return FontAwesomeIcons.twitter;
        }
        break;

        default: {
          return FontAwesomeIcons.home;
        }
      }
    }

Build Function

@override
Widget build(BuildContext context) {
  return Icon(getIconForName(icon), color: HexColor(color));
}

or 2. Create a Map

Map<String, IconData> iconMapping = {
  'facebook' : FontAwesomeIcons.facebook,
  'twitter' : FontAwesomeIcons.twitter,
  'home' : FontAwesomeIcons.home
};

Build Function

@override
Widget build(BuildContext context) {
  return Icon(iconMapping [icon], color: HexColor(color));
}

Solution 2:[2]

Just follow the below steps to achieve.

  1. Download the package [icons_helper]: https://pub.dev/packages/icons_helper from flutter packages

  2. Just add below code wherever you want a dynamic icon using JSON.

    a) FontAwesome icon: getIconGuessFavorFA(name:"ICON_NAME")

    b) Material icon: getIconGuessFavorMaterial(name:"ICON_NAME")

Example:

ExpansionTile(
  leading:  Icon(getIconGuessFavorMaterial(name:root.menuIcon)),  //Icon(FontAwesomeIcons.dashcube),            
  key: PageStorageKey<MobileMenuList>(root),
  title: Text(root.menuName),
  children: root.children.map(_buildTiles).toList(),
)

Note: If you face any error while complying like ('Error: Getter not found: 'haykal'.'). Just comment on the icon in 'icons_helper.dart'

Solution 3:[3]

I used the package reflectable and was able to reflect the existing modules fine. Here are examples for colors and icons constants.

import 'package:flutter/material.dart';


@GlobalQuantifyCapability(r"Icons",constReflector)
@GlobalQuantifyCapability(r"Colors",constReflector)
import 'package:reflectable/reflectable.dart';
import 'adaptive_icons.reflectable.dart'; // Import generated code.


class ConstReflector extends Reflectable {
  const ConstReflector()
      : super(declarationsCapability,staticInvokeCapability);
}

const constReflector = ConstReflector();

dynamic colorFromName(String name) {
  ClassMirror m =  constReflector.reflectType(Colors);
  return m.invokeGetter(name);
}

dynamic iconFromName(String name) {
  ClassMirror m =  constReflector.reflectType(Icons);
  return m.invokeGetter(name);
}

Solution 4:[4]

Use this package

     awesome_icons: ^1.1.0

     import 'package:awesome_icons/awesome_icons.dart';

      Icon(
        fontAwesomeIcons['Icon_name'],
        size: 24.0,
      ),

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Filled Stacks
Solution 2 Ganesh
Solution 3 Klaus Ries
Solution 4 Anandh Krishnan