Attach badge to node (the node's icon or else on the label)
Hello Kevin,
I’ve started to use your flutter treeview package, and it is really good!
I’m using JSON to create the treeview, and I need to show a badge on the node - either on the icon of the node or at the end of the label.
Is it possible to do this?
Míle Buíochas | Many thanks,
Niall.
Comments (13)
-
-
reporter Hi Kevin,
I’ve switched to the latest version (0.9.0+1), and the NodeIcon is gone (so all of my node icons are now gone). Is there any example anywhere for how to use the new dynamic nodeBuilder function?
I guess I need to use the nodeBuilder now to recreate my node icons?
Any chance you could update the main.dart example to show how to use this new functionality in version 0.9.0+1
Or even just a code snippet as an example would be great :)
Míle Buíochas | Many thanks,
Niall.
-
Niall, apologies for what happened with the icons in the code change. I wanted to get rid of NodeIcon to now support the native tree shaking feature in flutter. Adding icons to your node is as sample is using IconData now. Just pass something like:
Node(icon: Icons.folder)
-
I will work on updating the docs!!
-
reporter Hi Kevin, I’m using JSON to build the tree (see sample below)
With the latest version (0.9.0+1), the icons are not displayed anymore.
Do I need to make some changes to the JSON ‘icon’ element?
Is there a way to add a ‘Badge’ element to the JSON so that the icon has a badge? (see pic below)
Míle Buíochas | Many thanks,
Niall.
pic: tree with badge on icon (also badge displayed after ‘label’
here’s my JSON …
[{"id":2,"parentid":1,"label":"Bray","type":"building","key":"2","icon":{"codePoint":59553,"fontFamily":"fontawesome","fontPackage":null,"color":"grey"},"children":[{"id":3,"parentid":2,"label":"BrayGnd Floor","type":"floor","key":"3","icon":{"codePoint":59553,"fontFamily":"fontawesome","fontPackage":null,"color":"grey"},"children":[{"id":10,"parentid":3,"label":"BrayRoom1","type":"room","key":"10","icon":{"codePoint":61704,"fontFamily":"fontawesome","fontPackage":null,"color":"grey"},"children":[{"id":12,"parentid":10,"label":"WorkOrder 0827","type":"workorder","key":"12","icon":{"codePoint":62025,"fontFamily":"fontawesome","fontPackage":null,"color":"grey"},"children":[]},{"id":13,"parentid":10,"label":"WorkOrder 0828","type":"workorder","key":"13","icon":{"codePoint":62025,"fontFamily":"fontawesome","fontPackage":null,"color":"grey"},"children":[]}]}]},{"id":4,"parentid":2,"label":"Bray1st Floor","type":"floor","key":"4","icon":{"codePoint":59553,"fontFamily":"fontawesome","fontPackage":null,"color":"grey"},"children":[]}]},{"id":20,"parentid":1,"label":"Dublin","type":"building","key":"20","icon":{"codePoint":59553,"fontFamily":"fontawesome","fontPackage":null,"color":"grey"},"children":[]}]
-
Use the code below as an example. The class has a reader that can be used to convert your JSON data to Nodes and a builder that displayed a custom node with an indicator.
class NodeBuilder { static reader(List<Map<String, dynamic>> data) { return data.map((item) { String _key = item['key']; String _label = item['label']; var _data = item['type']; IconData _icon; List<Node> _children = []; //this is optional because the icon can be dynamically created in the builder if (item['icon'] != null) { Map<String, dynamic> _iconData = item['icon']; _icon = IconData( _iconData['codePoint'], fontFamily: _iconData['fontFamily'], fontPackage: _iconData['fontPackage'], ); } if (item['children'] != null) { _children = NodeBuilder.reader(List.from(item['children'])); } return Node( key: '$_key', label: _label, icon: _icon, data: _data, children: _children, ); }).toList(); } static builder(BuildContext context, Node node) { return ListTile( dense: true, title: Text(node.label, style: TextStyle(fontSize: 16)), contentPadding: EdgeInsets.all(0), horizontalTitleGap: 0, minVerticalPadding: 0, // subtitle: node.data == null ? null : Text(node.data), leading: makeIcon(node), ); } static makeIcon(Node node) { IconData _iconData; if (node.data == 'building') { _iconData = Icons.business; } else if (node.data == 'floor') { _iconData = Icons.all_inbox_outlined; } else if (node.data == 'room') { _iconData = Icons.monitor; } else if (node.data == 'workorder') { _iconData = Icons.insert_drive_file_outlined; } if (node.key == '2') { return _iconWithDot(node, _iconData, Colors.red); } else if (node.key == '3') { return _iconWithDot(node, _iconData, Colors.red); } else if (node.key == '10') { return _iconWithDot(node, _iconData, Colors.orange); } else if (node.key == '13') { return _iconWithDot(node, _iconData, Colors.green); } return _iconData == null ? Icon(Icons.circle, color: Colors.transparent) : Icon(_iconData, color: Colors.grey); } static _iconWithDot(Node node, IconData iconData, Color color) { return FittedBox( child: Stack( children: [ Icon(iconData, color: Colors.grey), Positioned( right: 0, child: Container( width: 10, height: 10, decoration: BoxDecoration( shape: BoxShape.circle, color: color, ), ), ), ], ), ); } }
I didn’t add the number to the badge but since the indicator is a
Container
, you can add anything you like. -
reporter Kevin,
Tá sé thar cionn ar fad! (it’s working great! It’s really, great)
Céad míle buíochas (hundred, thousand thanks!)
Niall.
-
- changed status to resolved
Explained solution using existing features
-
Hello Kevin,
I’m trying to use this class above to show a checkbox instead of an icon.
Basically i want to be able to select multiple nodes somehow.
My problem is that I’m not sure on how to implement it on the nodeBuilder level… follows screenshot of my code:
If you can help I’d appreciate it. Thanks in advance!
Best regards,
Marina
-
Hi Marina,
The code should look like…
nodeBuilder: (context, node) { return SomeWidget(); }
This is a link to the full code in the documentation. You can use something similar to display the checkbox.
-
Thanks a lot Kevin!
Btw, is there any way you of turning the data of the tree into a json string again?
-
On the tree view_controller there is the asMap method. It will return a Map<String, dynamic> object. And toString will return a json string.
Only thing to note here is that the json returned likely won’t match your original json object. If you look at the asMap method, you can possibly write something similar to export a Map that better matches your original json, especially if you store your object in the data property for each node.
Hope this helps.
-
Thanks for the tip, you were a huge help!
Have a nice day!
- Log in to comment
Hi Niall, it is not possible by default, but a recent update allows you to define your own builder on the TreeView widget. You can then add the badge wherever you like.