Coder Social home page Coder Social logo

embraceitmobile / animated_tree_view Goto Github PK

View Code? Open in Web Editor NEW
48.0 2.0 18.0 24.46 MB

Animated TreeView based on AnimatedList allows building fully customizable Nodes that can be nested to infinite levels and children.

Home Page: https://pub.dev/packages/animated_tree_view

License: MIT License

Swift 0.50% Objective-C 0.01% Dart 86.58% HTML 0.53% Kotlin 0.04% CMake 5.39% C++ 6.55% C 0.41%
dart tree-structure animated flutter tree-view tree-list animated-list nested-list

animated_tree_view's Introduction

animated_tree_view

A flutter package that provides a heirarchial Tree like data structure that can be visualized as a linear list view.

The widget is based on the Flutter’s familiar APIs of AnimatedList and SliverAnimatedList and can even be used as a replacement for these widgets. Each node can be completely customized using the TreeNodeWidgetBuilder that is used to build the nodes. All the mobile, web and desktop platforms are fully supported.

Animated Tree View Demo Animated Tree View Demo

Variants

There are four different variants each for the TreeView and the SliverTreeView. Based on the requirements and use case, you can use the simple, simpleTyped, indexed or the indexTyped variants.

TreeView

The simple TreeView uses the AnimatedList to build the tree view. It can be used for simple tree implementations where a combination with other scrollables is not required.

SliverTreeView

For implementing fancy lists and animations using slivers, SliverTreeView should be used. It is based on the SliverAnimatedList. It provides the same APIs as the normal TreeView and its usage is also the same. The SliverTreeView can be combined with other slivers in a CustomScrollView. Slivers provide significant performance improvements over the regular lists. Know more about slivers here.

.simple

The simple variant uses a Map data-structure to handle the Nodes and their children Using a Map makes the tree view more performant with a complexity on traversing the Nodes being O(n), where n is the level of the node. However the simple and simpleTyped variants of TreeView and SliverTreeView lack the indexed based operations like insertAt and removeAt etc.

.simpleTyped

The simpleTyped variant works the same as the simple variant however it is optimized for custom data types. The simpleTyped variant is recommended when using a custom data type and the indexed based operations are not needed. The analyzer is able to correctly infer the custom types when using the typed variants.

.indexed

The indexed variant uses a List data-structure to handle the Nodes and their children. This allows it to perform all the list based operations that require indices, like insertAt or removeAt. The drawback of using an TreeView.indexed or a SliverTreeView.indexed instead of *.simple variant is that the Node traversal operations on the *.indexed variants are more expensive with a complexity of O(n^m), where n is the number of children in a node, and m is the node level.

.indexTyped

The indexTyped works the same as the indexed variant however it is optimized for custom data types. The indexTyped variant is recommended when using a custom data type and the index based operations are also required. The analyzer is able to correctly infer the custom types when using the typed variants.

Features

  • Infinite levels and child nodes.
  • Animations for Node expansion and collapse.
  • Customizable indentation and scoping lines
  • Plenty of utility methods for adding, inserting, removing and collapsing/expanding nodes.
  • Easily traverse the tree laterally or vertically from the root to the leaf and back.
  • Tree Diff Util to compute the difference between two trees, and automatically apply the changes in the tree view.
  • Listenable changes using ValueNotifier and event Streams.

How to use

TreeView.simple

You can simply use the provided TreeNode or extend your data object from TreeNode<T>.

Note: If the key is omitted, then a unique key will be automatically assigned to the Node.

Finally, initialize the TreeView by providing it a builder.

TreeView.simple(
    tree: TreeNode.root(),
    builder: (context, node) {
        // build your node item here
        // return any widget that you need
        return ListTile(
          title: Text("Item ${node.level}-${node.key}"),
          subtitle: Text('Level ${node.level}'),
        );
    }
                

The level has been removed from the builder starting from version 2.0.0. To get the node level, use the node.level instead.

TreeView.indexed

The usage of TreeView.indexed is exactly the same as a simple TreeView. You only need to replace TreeNode with IndexedTreeNode or extend your YourCustomNode from IndexedTreeNode like this

Finally initialize the widget like this:

TreeView.indexed(
    tree: IndexedTreeNode.root(),
    builder: (context, node) {
        // build your node item here
        // return any widget that you need
        return ListTile(
          title: Text("Item ${node.level}-${node.key}"),
          subtitle: Text('Level ${node.level}'),
        );
    }
                

Please see this example for a more comprehsive code sample.

TreeView.simpleTyped

To use your custom data type CustomClass with TreeView, wrap your custom class inside the TreeNode like this TreeNode<CustomClass>

TreeView.simpleTyped<CustomClass, TreeNode<CustomClass>>(
    tree: TreeNode<CustomClass>.root(),
    builder: (context, node) {
      // build your node item here
      // return any widget that you need
      return ListTile(
          title: Text("Item ${node.level}-${node.key}"),
          subtitle: Text('Level ${node.data?.foo}'),
    );
  }     
)          

Please see this example for a more comprehsive custom object code sample.

SliverTreeView

The API and usage of SliverTreeView is the same as TreeView. You just need to wrap the SliverTreeView inside a CustomScrollView and provide it a Tree and a builder.

CustomScrollView(
    slivers: [
      SliverTreeView.simple(
        tree: TreeNode.root(),
        builder: (context, node) {
          // build your node item here
          // return any widget that you need
          return ListTile(
            title: Text("Item ${node.level}-${node.key}"),
            subtitle: Text('Level ${node.level}'),
          );
        },
      ),
    ],
  );

Please see this example for a more comprehsive sliver treeview sample.

Configuration and Behavior

Attributes Description
builder The builder function that is provided to the item builder. It lazily builds the list items. The built widget is passed to the AnimatedList or SliverAnimatedList's itemBuilder.
tree Tree that is used to populate the TreeView. If the tree is updated using any state management tools like setState or Bloc, then the TreeDiffUtil is used to get the diff between the two trees, and apply all the changes from the new tree onto the old tree.
scrollController Provide a scrollController for more granular control over scrolling behavior.
expansionIndicatorBuilder Builds an animated expansion indicator based on the node data. See ExpansionIndicator for available expansion indicators.
indentation The indentation style that is used to draw the indents for each node. Indentation.width will be multiplied by Node-Level before being applied as starting padding to the item widget. See Indentation for available indent styles and decoration.
onItemTap Callback that can be used to handle any action when an item is tapped or clicked.
showRootNode Flag to show the Root Node in the TreeView.
expansionBehavior The ExpansionBehavior provides control over the behavior of the node when it is expanded. See ExpansionBehavior for available behaviors.
onTreeReady Callback to get the TreeViewController when the TreeView is ready
padding The amount of space by which to inset the children.
primary (TreeView only) Whether this is the primary scroll view associated with the parent PrimaryScrollController.
physics (TreeView only) An object that can be used to control the position to which this scroll view is scrolled.
shrinkWrap (TreeView only) Whether the extent of the scroll view in the scrollDirection should be determined by the contents being viewed.

ExpansionBehavior

The ExpansionBehavior provides control over the behavior of the node when it is expanded. There are five available ExpansionBehaviors to choose from.

**Note: For using an ExpansionBehavior with a SliverTreeView, the same instance of an AutoScrollController needs to be provided to SliverTreeView and the CustoScrollView.

ExpansionBehavior.none ExpansionBehavior.snapToTop ExpansionBehavior.scrollToLastChild ExpansionBehavior.collapseOthers ExpansionBehavior.collapseOthersAndSnapToTop
No additional action will be taken on node expansion. The expanded node will be snapped to the top of the list. This ensures that the expanded node is always visible with maximum number of children. The list will be scrolled to the last child of the node if it is not already visible on screen. This ensures that the last child is always visible. Collapse all other nodes, only the current node will remain expanded. This ensures that only one node is expanded at one time. Collapse all other nodes, only the current node will remain expanded, also snap the node to the top of the list. This ensures that only one node is expanded at one time.
ExpansionBehavior.none ExpansionBehavior.snapToTop ExpansionBehavior.scrollToLastChild ExpansionBehavior.collapseOthers ExpansionBehavior.collapseOthersAndSnapToTop

ExpansionIndicator

The expansion indicator animates to change it's state based on the whether the node is collapsed or expanded. There are several built-in expansion indicators.

ChevronIndicator.rightDown ChevronIndicator.upDown PlusMinusIndicator
Right down indicator Up down indicator Plus minus indicator

noExpansionIndicatorBuilder can be used when no indicator is required.

ExpansionIndicator class can be extended to create a fully customizable expansion indicator.

Indentation

The indentations are drawn to show the node level and the connections between different nodes. The lineWidth, color and offset of the indentation can be customized with the Indentation.

By default IndentStyle.none is used and indentation lines are not drawn. Only the indentation.width will be used to add padding to the start of the content.

To draw indents change the style to IndentStyle.squareJoint or IndentStyle.roundJoint. To draw only scoping lines, change the style to IndentStyle.scopingLine.

IndentStyle.squareJoint IndentStyle.roundJoint IndentStyle.scopingLines IndentStyle.none
Indent.squareJoint Indent.squareJoint Indent.squareJoint Indent.squareJoint

Tree Diff Util

A TreeDiffUtil is used to determine the difference between two trees if the tree is updated using any state management tool like setState or Bloc etc.

For TreeView.simple, which uses a Map internally to store the child nodes, this is a simple difference operation on all the nodes of the tree. Complexity is O(2n), where n is the total number of nodes in the tree.

For TreeView.indexed, which uses a List internally to store the child nodes, it is a little more complex as Myer's algorithm is used to determine the difference in the children of each respective node. Complexity is O(N + D^2), where D is the length of the edit script. For more details see diffutil_dart.

Available APIs

Node

Method TreeView IndexedTreeView Description
isRoot Getter to check if the node is a root
isLeaf Getter to check if the node is a Leaf
root (getter) Getter to get the root node. If the current node is not a root, then the getter will traverse up the path to get the root.
level Getter to get the level i.e. how many iterations it will take to get to the root.
elementAt Utility method to get a child any child node at the path. The path contains the keys of the node separated by period . e.g. #grandparent_key.#parent_key.#node
add Add a child to the node
addAll Add a collection of nodes to the node
remove Remove a child from the node
removeAll Remove a collection of nodes from the node
removeWhere Remove children from the node that meet the criterion in the provided test
delete Delete the current node
clear Remove all the child nodes: after this operation the children are empty
first Get/Set first child in the node
last Get/Set last child in the node
insert Insert a child at an index in the node
insertAll Insert a list of children at an index in the node
insertAfter Insert a child after the node
insertBefore Insert a child before the node
removeAt Remove a child at the index
firstWhere Get the first child node that matches the criterion in the test.
lastWhere Get the last child node that matches the criterion in the test.
indexWhere Get the index of the first child node that matches the criterion in the test.

TreeViewController

The TreeViewController provides utility methods that allow controlling the TreeView programmatically.

Method Description
elementAt Get any item at path from the root. The keys of the items to be traversed should be provided in the path
root Root node of the TreeView
scrollToIndex Allows to scroll to any item with index in the list. If you do not have the index of the item, then use the alternate scrollToItem method item instead.
scrollToItem Utility method to scroll to any visible item in the tree.
toggleExpansion Utility method to expand or collapse a tree node.
expandNode Utility method for expanding a tree node.
collapseNode Utility method for collapsing a tree node.
expandAllChildren Utility method for expanding all the children of a node. It can be also be used to recursively expanded all the child nodes until the leaf is reached

Future Goals

  • Add RTL support
  • Add support for 2D scrolling when the 2D scrolling API becomes available.

animated_tree_view's People

Contributors

jawwad-hassan89 avatar wasimshigri avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

animated_tree_view's Issues

question for real world usecase

Hi @jawwad-hassan89 ,

Hope you are all well !

I am just dropping this message as I would like to create a teampass (https://teampass.net/) clone with flutter.

What would you advice me to use as an architecture for managing permission rights to items categories with view/edit/delete capability. I found flutter_rbac or dart-casbin

Screenshot of teampass:
pf_tp_5
Thanks for any insights or inputs to help me to boostrap this project.

The bottleneck I see, is that have I hace 30k items to hook in the the tree view. Is It possible to make the tree view searchable ?

Cheers,
Luc

Unhandled Exception: Bad state: No element

When tapping the indented area in front of the card, throw Unhandled Exception: Bad state: No element at animated_list_controller.dart:145

TreeView.simple(
        key: globalKey,
        tree: tree,
        builder: (context, level, item) => Card(
              child: ListTile(
                title: Text("Item ${item.level}-${item.key}, ${data?["title"] ?? ""}"),
                subtitle: Text("Level $level"),
              ),
        ),
)

2D Scrolling

Flutter has implemented the 2d scrolling api, so this issue is to alert the developer to complete the todo for 2d scrolling that is present in the readme.

Exception has occurred.

Hello, I implemented TreeView.simpleTyped but when I enter the page I get this error:

Exception has occurred.
ActionNotAllowedException (ActionNotAllowedException:
The insertNodes stream is not allowedfor the ListenableNode. The index based operations like 'insert' are not implemented in ListenableNode})

after that, the node tree appears normally. Can someone help me?

Dynamic change of root

Hi,

Thanks very much for this package.
I seem to have an issue when I change the root node and rebuild the treeview widget.
The treeview builds the same but when the build method is called it seems to remember the old root nodes. The build method is called with nodes that no longer exist in the new root node.
As an example if I create a root node with 3 nodes the build method is correctly called 3 times.
Then if I change the root node to just 1 node and rebuild then the builder is called 4 times.
This is the root node output - IndexedNode{children: [IndexedNode{children: [], key: 1, parent: IndexedNode{children: [...], key: /, parent: null}}], key: /, parent: null}

I am using the GetIt mixin with a stateless widget to create the TreeView.

Many Thanks
Garth

Error: Bad state: No element

When loading the view, I receive the following stack trace.
I cannot figure out what the issue is. Whether it is an issue in my code or in the module.

As far as I understand, the error is thrown by animated_tree_view. Can you confirm that?

My indexed tree only has two levels after root. 5 level 1 entries. the first two level 1 entries have 2 level 2 entries.

Error: Bad state: No element
dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart 266:49  throw_
dart-sdk/lib/_internal/js_dev_runtime/private/js_array.dart 337:5             last]
packages/animated_tree_view/tree_view/animated_list_controller.dart 145:44    <fn>
dart-sdk/lib/async/future.dart 424:39                                         <fn>
dart-sdk/lib/_internal/js_dev_runtime/private/isolate_helper.dart 48:19       internalCallback
Error: Bad state: No element
dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart 266:49  throw_
dart-sdk/lib/_internal/js_dev_runtime/private/js_array.dart 337:5             last]
packages/animated_tree_view/tree_view/animated_list_controller.dart 145:44    <fn>
dart-sdk/lib/async/future.dart 424:39                                         <fn>
dart-sdk/lib/_internal/js_dev_runtime/private/isolate_helper.dart 48:19       internalCallback

Tree is getting collapsed moving from one tab to another/screen

My tree expands for the first time, but when I move to another tab or page, it gets collapsed. I'm using GetX. I need my tree to remain expanded even if I move from one tab to another. How can I achieve this? I've attached code snippets and a video of the issue I'm facing.

class RelationTreeView extends StatefulWidget {
  @override
  State<RelationTreeView> createState() => _RelationTreeViewState();
}

class _RelationTreeViewState extends State<RelationTreeView> {
  final controller = Get.find<BookScanController>();

  @override
  Widget build(BuildContext context) {
    return GetBuilder<BookScanController>(
      builder: (_) => Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          _heading(context),
          TreeView.simple(
            shrinkWrap: true,
            key: controller.globalKey,
            tree: controller.relationShipTree,
            showRootNode: false,
            expansionBehavior: ExpansionBehavior.scrollToLastChild,
            expansionIndicatorBuilder: (context, node) =>
                ChevronIndicator.upDown(
              tree: node,
              color: Theme.of(context).hintColor,
              padding: const EdgeInsets.all(15),
            ),
            indentation: Indentation(
              style: IndentStyle.squareJoint,
              thickness: 2.5,
              color: Theme.of(context).hintColor,
            ),
            builder: (context, node) => Container(
              margin: const EdgeInsets.only(top: 10, left: 10, right: 10),
              child: ListTile(
                leading: _.selectedPatientInfo == node.data
                    ? Icon(
                        Icons.check_circle_rounded,
                        size: 16,
                        color: Theme.of(context).indicatorColor,
                      )
                    : Icon(
                        Icons.check_circle_rounded,
                        size: 16,
                        color: Theme.of(context).disabledColor,
                      ),
                title: Text(
                  "${node.key}".toTitleCase(),
                  style: Theme.of(context).textTheme.bodySmall,
                ),
                subtitle: _patientCard(
                  node.data as Map<String, dynamic>?,
                  context,
                  node.level == 1 ? true : false,
                ),
                onTap: () {
                  controller.updateSelectedPatientInfo(
                    node.data as Map<String, dynamic>?,
                  );
                },
              ),
            ),
          ),
        ],
      ),
    );
  }

bookscancontroller.dart

class BookScanController extends GetxController{
   final globalKey = GlobalKey<TreeViewState>();

  TreeViewController? get tccontroller => globalKey.currentState?.controller;
  
   TreeNode relationShipTree = TreeNode.root();
  
   void _expandAllNodes() {
    tccontroller?.toggleExpansion(
      relationShipTree,
    );
  }
bandicam.2023-11-18.17-23-25-858.mp4

Question: Is there a way to deactivate "toggleExpansion" ?

Hi,
i'm looking for a way to, based on the item, to deactivate the expansion/collapse of its children.
Is there a way currently ?

Or is it something you want to achieve?
If yes, my suggestion would be something like, i could do the PR:

  Future<void> toggleExpansion(ITreeNode<Data> item) async {
    if (item.isExpandable == false) {
      return;
    }
    if (item.isExpanded)
      await collapseNode(item);
    else {
      expandNode(item);
      await applyExpansionBehavior(item);
    }
  }

Greets!

How to load the tree data only when it is needed?

I'm looking for a behavior similar to the java swing JTree. I want to build a tree model that allows the tree data to be loaded only when it is needed. My app's data is stored in a database and it is not practical to load it all into memory to build all the nodes up front. I suspect I can implement this but I'm curious since all the example code shows cases where the tree is loaded into memory.

Lookup TreeNode by Key?

Is there any way to look up a TreeNode by a key? I want to expand a TreeNode within the tree, but I don't have a reference to the node, just its key.

Question: Editing Tree Hierarchy

Is there a way if the user have a flat list of items/nodes, to edit the hierarchy; to move certain nodes under a specific parent and vice versa?

Functionality like slide to right to (indent) the node and make it nested under the parent or dropdown to choose (Parent of Child from the list). (ex. Notes or Checklist app)

Something like DragAndDropLists or nested_reorderable_list but with the same functionality animated_tree_view has where you can add or delete children

Build custom ExpansionIndicator

I am slightly confused about building custom ExpansionIndicator, do not know how to do it. Probably you can provide a small example.

expandAllChildren causes duplicate tree nodes

Good evening!

Thank you for creating this project. It has been awesome to use!

I have run into a bug using the new expandAllChildren feature released in version 2.0.0. When calling that method on the TreeViewController, it creates duplicates of all the items in the tree. I was able to reproduce the issue in your example Flutter app.

Here is a screenshot of the problem. Notice that there are two instances of Item 1-0E. All I did to get into this state is click the Expand all button exactly once. If you click it a few times then the duplicates are cleared out.

image

Custom name for node

Hi,

Currently when adding a new child or node, it is adding a name based on level and key.

What about adding a custom name? Is there any sample for this matter. I am trying to open a dialog to read the name and then I changed the code, but I am receiving some errors.

Feature Request: allow items reordering

Hi, thank you for this package it's truly amazing!

I would like to suggest a new feature. It would be relly cool if this package could suppport item reorder using drag and drop.
Basically the user should be able to pick up a node of the tree and drag and drop it anywhere else in the tree at the same level.

What I'm suggesting is a behavior similar to this, but adapted to work on a tree structure:
expansion_tiles

There currently is no package that supports item reordering on more than 2 levels, and I believe this package has the structure to support this freature without any crazy work necessary, since it is already based on ReorderableListView.

I created a fork and started working on this, but my skills and understanding of the structure of this package are insuficcient to complete the task.

Expand all nodes default or special node

Hi, Is there any way to expand all child nodes or specified node after all view build is complete? I changed the 'isExpanded' property of the TreeNode to true but it had no effect.

Please make AnimationController in ExpansionIndicatorState public

Hi, thanks for the great package. A minor thing though:
For simplifying the process of creating a custom ExpansionIndicator (extending the abstract ExpansionIndicatorState class), it would be nice to get public access to its AnimationController.

Right now it is private:
late final AnimationController _controller = AnimationController(
duration: animationDuration,
vsync: this,
);

Could you make it public by removing the underscore pls?

Not generating unique keys for the nodes

I got this error (

if (children.containsKey(node.key)) throw DuplicateKeyException(node.key);
) when I have a Node with a lot of children.

In my case it happens (sometimes) when I open this tree location (/bin/), where there are a lot of children.

I bypass this error by providing a String key to every node.

I suggest that maybe you can provide an int instead of String (2^64 unique keys is enough).

Also I tried to use int keys like this: '$keyIndex++', but I got same error: (0 key is yet used, 1 key is yet used, ...).

Get objects in the tree

Hello, can somebody help me? I trying to get all objects in the tree so I can convert it to json to send to backend, but I can't understand how to do it.

Order issue when add a new node

Package version - 2.1.0
Type of tree - TreeView.simpleTyped
Flutter version - 3.13.6

There is an order issue when I add a node to a parent node where there are already expanded nodes, a new nodes is added to the wrong place

Screen.Recording.2023-11-13.at.10.37.03.mov

How to refresh UI state for node after check-box is clicked on such node?

I need a tree with a checkbox on each of its nodes. My current problem is that the checkbox ui state does not change right after I click the checkbox for that node, but it is then updated correctly when I expand or shrink the tree.

How can I make this work so that when a checkbox os pressed it's UI wii change too on the node?

onItemTap exception

hey bro,I set onItemTap listener,it not works and got exception,maybe you use wrong data in that line.

onTap: onTap == null ? null : () => onTap!(item),

my exception

E/flutter ( 6743): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: type 'TreeNode<BusinessTreeNode<dynamic>>' is not a subtype of type 'BusinessTreeNode<dynamic>'
E/flutter ( 6743): #0      ExpandableNodeItem.build.<anonymous closure> (package:animated_tree_view/tree_view/expandable_node.dart:51:49)
E/flutter ( 6743): #1      _ExpandableNodeContainer.build.<anonymous closure> (package:animated_tree_view/tree_view/expandable_node.dart:93:51)
E/flutter ( 6743): #2      GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:253:24)
E/flutter ( 6743): #3      TapGestureRecognizer.handleTapUp (package:flutter/src/gestures/tap.dart:627:11)
E/flutter ( 6743): #4      BaseTapGestureRecognizer._checkUp (package:flutter/src/gestures/tap.dart:306:5)

Unhandled Exception: Exception: Animated list state not found from GlobalKey<AnimatedListState>

My code:

for (var element in _rootNode.childrenAsList) { if (element.key == parentKey.toString()) { try { element .add(TreeNode(key: context.uid.toString())); } catch (e) {} return; } }

Exception:

[ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: Exception: Animated list state not found from GlobalKey
#0 _AnimatedListState.insertItem
tree_view.dart:495
#1 AnimatedListController.insert
animated_list_controller.dart:65
#2 AnimatedListController.insertAll
animated_list_controller.dart:70
#3 AnimatedListController.expandNode
animated_list_controller.dart:116
#4 AnimatedListController.handleAddItemsEvent
animated_list_controller.dart:208
#5 _RootZone.runUnaryGuarded (dart:async/zone.dart:1593:10)
#6 _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:339:11)
#7 _DelayedData.perform (dart:async/stream_impl.dart:515:14)

scroll to index 3.0

can you upgrade to scroll to index 3.0 that is compatible with flutter 3 ?

layout error

tree view need x y scroll.
otherwise the ui layout is error
Screen Shot 2021-06-27 at 4 52 48 PM

expandAllChildren

Upon initial loading of the tree, it can be completely unfolded. But upon going back to the previous page and subsequently redirecting to this page, the tree does not unfold anew.

How to detect if node is expanding or shrinking in onItemTap method?

I am trying to dynamically lazy load data as long as user clicks on the e.g. Folder.

I was thinking about capturing the click using onItemTap and then detect if node is "expanding" in order to dynamically load and inject nodes.

Unfortunately in my case (using file_explorer_sample.dart) example: node.isExpanded is always true regarding if node is opening or closing.

onItemTap: (node) async {
  if (node.isExpanded) {
   // Why always true?
  }
}

Any idea how to detect current state of the node in onItemTap?

Related: #37

Why node.data can be null?

If I declare the tree data type as not null it should preserve this type. If I want to make it nullable I just can put <MyType?>.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.