Closed merskip closed 3 years ago
The full version of serializing and deserializing look like this:
import 'package:flutter/material.dart';
import 'package:flutter_iconpicker/IconPicker/Packs/Cupertino.dart'
as Cupertino;
import 'package:flutter_iconpicker/IconPicker/Packs/FontAwesome.dart'
as FontAwesome;
import 'package:flutter_iconpicker/IconPicker/Packs/LineIcons.dart'
as LineAwesome;
import 'package:flutter_iconpicker/IconPicker/Packs/Material.dart' as Material;
import 'package:flutter_iconpicker/IconPicker/Packs/MaterialOutline.dart'
as MaterialOutline;
import 'package:flutter_iconpicker/Models/IconPack.dart';
Map<String, dynamic> serializeIcon(IconData icon, {IconPack iconPack}) {
if (iconPack == null) {
if (icon.fontFamily == "MaterialIcons")
iconPack = IconPack.material;
else if (icon.fontFamily == "outline_material_icons")
iconPack = IconPack.materialOutline;
else if (icon.fontFamily == "CupertinoIcons")
iconPack = IconPack.cupertino;
else if (icon.fontPackage == "font_awesome_flutter")
iconPack = IconPack.fontAwesomeIcons;
else if (icon.fontPackage == "line_awesome_flutter")
iconPack = IconPack.lineAwesomeIcons;
else
iconPack = IconPack.custom;
}
switch (iconPack) {
case IconPack.material:
return {
'pack': "material",
'key': _getIconKey(Material.icons, icon),
};
case IconPack.materialOutline:
return {
'pack': "materialOutline",
'key': _getIconKey(MaterialOutline.materialOutline, icon),
};
case IconPack.cupertino:
return {
'pack': "cupertino",
'key': _getIconKey(Cupertino.cupertinoIcons, icon),
};
case IconPack.fontAwesomeIcons:
return {
'pack': "fontAwesomeIcons",
'key': _getIconKey(FontAwesome.fontAwesomeIcons, icon),
};
break;
case IconPack.lineAwesomeIcons:
return {
'pack': "lineAwesomeIcons",
'key': _getIconKey(LineAwesome.lineAwesomeIcons, icon),
};
break;
case IconPack.custom:
return {
'pack': "custom",
'iconData': {
'codePoint': icon.codePoint,
'fontFamily': icon.fontFamily,
'fontPackage': icon.fontPackage,
'matchTextDirection': icon.matchTextDirection,
}
};
default:
return null;
}
}
IconData deserializeIcon(Map<String, dynamic> iconMap) {
try {
final pack = iconMap['pack'];
final iconKey = iconMap['key'];
switch (pack) {
case "material":
return Material.icons[iconKey];
case "materialOutline":
return MaterialOutline.materialOutline[iconKey];
case "cupertino":
return Cupertino.cupertinoIcons[iconKey];
case "fontAwesomeIcons":
return FontAwesome.fontAwesomeIcons[iconKey];
case "lineAwesomeIcons":
return LineAwesome.lineAwesomeIcons[iconKey];
case "custom":
final iconData = iconMap['iconData'];
return IconData(
iconData['codePoint'],
fontFamily: iconData['fontFamily'],
fontPackage: iconData['fontPackage'],
matchTextDirection: iconData['matchTextDirection'],
);
default:
return null;
}
} catch (e) {
return null;
}
}
String _getIconKey(Map<String, IconData> icons, IconData icon) =>
icons.entries.firstWhere((iconEntry) => iconEntry.value == icon).key;
Nice would be optimize serializing for a large number of it.
Example of the result:
{
"pack": "material",
"key": "camera"
}
The full version of serializing and deserializing look like this:
import 'package:flutter/material.dart'; import 'package:flutter_iconpicker/IconPicker/Packs/Cupertino.dart' as Cupertino; import 'package:flutter_iconpicker/IconPicker/Packs/FontAwesome.dart' as FontAwesome; import 'package:flutter_iconpicker/IconPicker/Packs/LineIcons.dart' as LineAwesome; import 'package:flutter_iconpicker/IconPicker/Packs/Material.dart' as Material; import 'package:flutter_iconpicker/IconPicker/Packs/MaterialOutline.dart' as MaterialOutline; import 'package:flutter_iconpicker/Models/IconPack.dart'; Map<String, dynamic> serializeIcon(IconData icon, {IconPack iconPack}) { if (iconPack == null) { if (icon.fontFamily == "MaterialIcons") iconPack = IconPack.material; else if (icon.fontFamily == "outline_material_icons") iconPack = IconPack.materialOutline; else if (icon.fontFamily == "CupertinoIcons") iconPack = IconPack.cupertino; else if (icon.fontPackage == "font_awesome_flutter") iconPack = IconPack.fontAwesomeIcons; else if (icon.fontPackage == "line_awesome_flutter") iconPack = IconPack.lineAwesomeIcons; else iconPack = IconPack.custom; } switch (iconPack) { case IconPack.material: return { 'pack': "material", 'key': _getIconKey(Material.icons, icon), }; case IconPack.materialOutline: return { 'pack': "materialOutline", 'key': _getIconKey(MaterialOutline.materialOutline, icon), }; case IconPack.cupertino: return { 'pack': "cupertino", 'key': _getIconKey(Cupertino.cupertinoIcons, icon), }; case IconPack.fontAwesomeIcons: return { 'pack': "fontAwesomeIcons", 'key': _getIconKey(FontAwesome.fontAwesomeIcons, icon), }; break; case IconPack.lineAwesomeIcons: return { 'pack': "lineAwesomeIcons", 'key': _getIconKey(LineAwesome.lineAwesomeIcons, icon), }; break; case IconPack.custom: return { 'pack': "custom", 'iconData': { 'codePoint': icon.codePoint, 'fontFamily': icon.fontFamily, 'fontPackage': icon.fontPackage, 'matchTextDirection': icon.matchTextDirection, } }; default: return null; } } IconData deserializeIcon(Map<String, dynamic> iconMap) { try { final pack = iconMap['pack']; final iconKey = iconMap['key']; switch (pack) { case "material": return Material.icons[iconKey]; case "materialOutline": return MaterialOutline.materialOutline[iconKey]; case "cupertino": return Cupertino.cupertinoIcons[iconKey]; case "fontAwesomeIcons": return FontAwesome.fontAwesomeIcons[iconKey]; case "lineAwesomeIcons": return LineAwesome.lineAwesomeIcons[iconKey]; case "custom": final iconData = iconMap['iconData']; return IconData( iconData['codePoint'], fontFamily: iconData['fontFamily'], fontPackage: iconData['fontPackage'], matchTextDirection: iconData['matchTextDirection'], ); default: return null; } } catch (e) { return null; } } String _getIconKey(Map<String, IconData> icons, IconData icon) => icons.entries.firstWhere((iconEntry) => iconEntry.value == icon).key;
Nice would be optimize serializing for a large number of it.
Example of the result:
{ "pack": "material", "key": "camera" }
hey @merskip sorry for my late response. I was very busy since last year and I have to investigate into this asap.
I see here a crucial bug, where I already got some ideas and yeah: your solution looks promising!
I'll write you here back, as soon as I finished the work on it :)
As far as I know it's only about the material design code points, they could change at any time. This is quite annoying - not sure how other packages handle code points.
Thank you for fixing it!
It is good to implement new functionality for icon serialization but it would be also good to notify users about breaking changes. I used method iconDataToMap
/mapToIconData
and after upgrage the package I got an error because you removed those ones and created news ones. Please update change log.
thank you @Ahmadre i will check it out later! : - )
It is good to implement new functionality for icon serialization but it would be also good to notify users about breaking changes. I used method
iconDataToMap
/mapToIconData
and after upgrage the package I got an error because you removed those ones and created news ones. Please update change log.
Oh yeah, I just updated the README, but I will also update the Changelog and mark a big "Breaking Change" section 👍🏼
It is good to implement new functionality for icon serialization but it would be also good to notify users about breaking changes. I used method
iconDataToMap
/mapToIconData
and after upgrage the package I got an error because you removed those ones and created news ones. Please update change log.
Breaking Change is now mentioned in the changelog. Thank you for the reminder here :)
There is another breaking change in my case, for previously stored icons there is no pack defined and the function deserializeIcon returns null Sample of stored icon: {codePoint: 62948, fontFamily: FontAwesomeSolid, fontPackage: font_awesome_flutter, matchTextDirection: false}
I fixed it by creating an IconData from the data if deserializeIcon returns null. I think this should be the default for deserializeIcon to handle previously saved icons.
IconData base64ToIconData(String iconJson) {
IconData iconDataResult;
if (iconJson == null || iconJson == '') {
iconDataResult = Icons.block;
} else {
Map<String, dynamic> data = json.decode(utf8.decode(base64.decode(iconJson)));
iconDataResult = deserializeIcon(data);
if (iconDataResult == null) {
iconDataResult = IconData(
data['codePoint'],
fontFamily: data['fontFamily'],
fontPackage: data['fontPackage'],
matchTextDirection: data['matchTextDirection'],
);
}
if (iconDataResult == null) {
iconDataResult = Icons.block;
}
}
return iconDataResult;
}
Hello,
I wanted to use icons as a symbol of a category. I need to store the selected icon in a database. The simplest way is store fields:
codePoint
,fontFamily
,fontPackage
andmatchTextDirection
. This solution is suggested in README file and in a few Stackoverflow posts but this doesn't work. After some time the icons are different.In REDME there is an example:
IconData(0xe3af, fontFamily: 'MaterialIcons'); // Icons.camera
but now under
0xe3af
is:static const IconData record_voice_over_outlined = IconData(0xe3af, fontFamily: 'MaterialIcons');
This causes changing icons after some time. In the database, I store the above four fields. This means we cannot trust values for a long time. Using the code
Icons.camera
is ok and works for all time.I think we need to store icons in a different way.
I think something like that: