How to scroll to a key

Issue #24 new
NeoLink Net created an issue

Thank you for creating the awesome Tree view. When a tree view controller is initialized with a selected key , it doesn’t scroll to the node of selected key, which is not displayed on the current screen. I need to manually scroll down to see the selected key node.

Any suggestions, will be helpful. I also didn’t see any api calls like scrolltoKey().

I am using an expanded widget in a column without any scroll bars.

child: Column(
          mainAxisAlignment: MainAxisAlignment.start,
          children: <Widget>[
Expanded(
     child: Container(
       decoration: BoxDecoration(
         borderRadius: BorderRadius.circular(10),
       ),
       padding: EdgeInsets.all(10),
       child: buildprojectTree(),

     ),
 ),
 ],
 ),

  _treeViewController = TreeViewController(
          children:nodes,selectedKey: "P:41;F:13");

 Widget buildprojectTree() {
 return TreeView(
        controller: state._treeViewController,
        allowParentSelect: false,
        supportParentDoubleTap: false,
       primary: true,
       onExpansionChanged: (key,expanded) {

         Node node = state._treeViewController.getNode(key);
         if (node != null)
           {
             List<Node> updated;
             updated = state._treeViewController.updateNode(
                 key, node.copyWith(expanded: expanded));
             state.setState(() {
               state._treeViewController = state._treeViewController.copyWith(children: updated);
             });

             }
       },
        onNodeTap: (key) {

          state.setState(() {
            state._treeViewController =
               state._treeViewController.copyWith(selectedKey: key);
          });

        },
      theme: _treeViewTheme,
    );
    }

Comments (3)

  1. Gustav Gussi

    I was going to ask author to allow to add scroll controller parameter for tree but in time I noticed the property primary. 🙂 So I here it is my positioning idea:
    Wrap the TreeView with PrimaryScrollController.

    // Somewhere in model declaration
    class Zone {
      ...
      int treeIndex; // mandatory prop which contains index in tree view from 0 to infinity
      ...
    }
    
    // Somewhere in tree data prepatation.
    final List<Zone> zones = prepareZoneTree(); // List which represents a tree. Each zone must have `treeIndex` initialized.
    final List<Node<Zone>> nodes = ...; // convert List<Zone> to List<Node<Zone>>
    
    // Somewhere in initState
    scrollController = ScrollController();
    WidgetBingings.instance.addPostFrameCallback((_) {
      final node = treeController.getNode('selected key'); // get the node by selected key
      final zone = node.data; // data prop contains `Zone` instance.
      // The height of tree item can be calculated by two methods: 
      //  1) height of tree list (using LayoutBuilder temporarily) / number of visible nodes; 
      //  2) as widget now supports item builder it is possible to calc the item height using RenderBox.
      final offset = zone.treeIndex * _kTreeNodeHeight; // constant contains the height of item
      if (scrollController.hasClients) {
        scrollController.animateTo(
          offset: offset, 
          duration: Duration(milliseconds: 250,
          curve: Curves.easeIn));
      }
    });
    
    // Somewhere in build
    return PromaryScrollController(
      controller: scrollController,
      child: TreeView(
        nodes: nodes,
        ...
      ),
    );
    

  2. Stefan Kiss

    First thank you for the excellent widget.
    I would also like this functionality. (scrollTo(node) or Node.scrollTo() method)

    The solution proposed by Gustav Gussi will probably work but feels alot like a hack.
    So if you have time to get this implement this functionality it would be awesome!

    Thank you,

    Stefan

  3. Ali Burak ERDOĞAN

    Gustav’s solution works except for tree nodes with different heights. I think Scrollable.ensureVisible should be called inside TreeView widget's ListView. Otherwise, accurately estimating the offset of the aimed node is very difficult. We can’t access TreeNode widgets inside TreeView, so calling Scrollable.ensureVisible from outside is impossible either.

  4. Log in to comment