baumths / flutter_tree_view

A Flutter collection of widgets and slivers that helps bringing your hierarchical data to life.
https://baumths.github.io/flutter_tree_view
MIT License
175 stars 62 forks source link

support for the same node in mutiple places in the tree, please, like directed graph traversal.. #91

Open YotamAviv opened 4 months ago

YotamAviv commented 4 months ago

I'm using this tree in a project that allows navigating posts, their authors, comments, authors of the comments, other posts by those folks, etc..., and so it's possible and absoultely expected to be able to navigate to the same post or author through a variety of paths. When this happens, I suffer the old and familiar, "Multiple widgets used the same GlobalKey." (I can use UniqueKey instances to avoid the errors, but the expansion state of the tiles are tied to the Nodes.) I looked at the TreeController code, and it looks like it'd be possible to hold the expansion state of tiles not using the Node () but by using the TreeTile Widget instead, and this would support my use cleanly. But it might be more complicated.

I hope that submitting this request here is appropriate. I'm new to open source development in GitHub. Please let me know if you'd be interested in supporting my use case. I'd be available to help.

Thanks!

baumths commented 4 months ago

Hey @YotamAviv, could you provide a small reproducible example of your tree view code? I'm pretty sure this can be solved on the user end, without having to edit the package.

For example, you could use the following pattern for your keys: GlobalObjectKey('$pageName#${node.id}')

YotamAviv commented 4 months ago

Hi, Matheus,

could you provide a small reproducible example of your tree view code? I don't have anything ready right to easily send right now, and I'll be traveling shortly (moving actually). I should be able to send a package that compiles and demonstrates this mid next next week.

But here are is a snippet from my code:

class _MyTreeViewState extends State { late final TreeController treeController;

_MyTreeViewState() { OouTop().fetch(); }

@override void initState() { super.initState();

treeController = TreeController( roots: OouTop().getRoots(), childrenProvider: (OouNode node) => node.getChildren(), );

// Kudos: flutter_tree_view/example/lib/src/examples/filterable.dart
// See more code there and elsewhere.
OouTop().addListener(() {
  treeController.roots = OouTop().getRoots();
  treeController.rebuild();
  if (mounted) {
    setState(() {});
  }
});

}

In TreeController.dart, I see:

bool getExpansionState(T node) { return _toggledNodes.contains(node) ^ defaultExpansionState; }

There are good comments in that file about how I could subclass TreeController and allow a Node instance to deal with its own expansion state, but what I currently have is the same Node instance being found multiple times in the same tree as tree nodes are expanded. That is, 2 distinct Node instances (consider, Seattle and San Francisco) return the same Node instance (consider Portland) as one of their children. And so the Portland Node instance can be in one tree under 2 different parents. Mine isn't a tree; it's a directed graph. When I click one of those Portland tiles, the other also expands - they necessarily have the same expansion state always.

Thank you for the quick response! -Tom

On Mon, Apr 22, 2024 at 7:23 PM Matheus Baumgarten @.***> wrote:

Hey @YotamAviv https://github.com/YotamAviv, could you provide a small reproducible example of your tree view code? I'm pretty sure this can be solved on the user end, without having to edit the package.

For example, you could use the following pattern for your keys: GlobalObjectKey('$pageName#${node.id}')

— Reply to this email directly, view it on GitHub https://github.com/baumths/flutter_tree_view/issues/91#issuecomment-2071113044, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABER4YRYNCV4IKKPQJZI5K3Y6WLY3AVCNFSM6AAAAABGTVOS66VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDANZRGEYTGMBUGQ . You are receiving this because you were mentioned.Message ID: @.***>

baumths commented 4 months ago

Make sure your nodes have a unique id (usually the one that comes from the database). Then make sure your tree node class overrides the equality operator ==. You could also use give each TreeView its own TreeController.

Hope the moving goes as smoothly as it can go! I'm going through a big one at the moment too. 🙃